You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++14中结合复杂谓词使用std::enable_if的编译问题解决

问题:C++14下自定义or_模板实现类型约束编译失败

工作环境仅支持C14,需用std::enable_if为函数添加类型约束,因无法使用C17的std::disjunction,从libc的type_traits头文件引入or_模板并封装为IsVectorOrList结构体。但将函数返回类型约束改为typename std::enable_if<IsVectorOrList<T>::value, void>::type时编译报错,直接使用typename std::enable_if<IsVector<T>::value || IsList<T>::value, void>::type则正常编译。

原代码

#include <type_traits>
#include <iostream>
#include <vector>
#include <list>

template <typename T>
struct IsVector : public std::false_type {};

template <typename T>
struct IsVector<std::vector<T>> : public std::true_type {};

template <typename T>
struct IsList : public std::false_type {};

template <typename T>
struct IsList<std::list<T>> : public std::true_type {};

// taken from libc type_traits
template <bool, typename, typename>
struct conditional;

template <typename...>
struct or_;

template <>
struct or_<> : public std::false_type {};

template <typename _B1>
struct or_<_B1> : public _B1 {};

template <typename _B1, typename _B2>
struct or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type {};

template <typename _B1, typename _B2, typename _B3, typename... _Bn>
struct or_<_B1, _B2, _B3, _Bn...> : public conditional<_B1::value, _B1, or_<_B2, _B3, _Bn...>>::type {};
// ---

template <typename T>
struct IsVectorOrList : public or_<IsVector<T>, IsList<T>>::type {};

template <typename T>
typename std::enable_if<IsVector<T>::value || IsList<T>::value, void>::type
// replacing with this line does not work
//typename std::enable_if<IsVectorOrList<T>::value, void>::type
foo(const T& list)
{
    for (const auto& item : list)
    {
        std::cout << item << std::endl;
    }
}


int main()
{
    foo(std::vector<int>{17, 42});
    foo(std::list<float>{1.0, 2.71, 3.14});
}

编译错误信息

traits.cpp:32:8: error: invalid use of incomplete type ‘struct conditional<true, IsVector<std::vector<int> >, IsList<std::vector<int> > >’
   32 | struct or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type {};
      |        ^~~~~~~~~~~~~
traits.cpp:20:8: note: declaration of ‘struct conditional<true, IsVector<std::vector<int> >, IsList<std::vector<int> > >’
   20 | struct conditional;
      |        ^~~~~~~~~~~

错误原因

你只对conditional结构体做了前向声明,没有提供完整的定义。C++11及以后标准库已经提供了std::conditional,但你自定义的conditional未实现,导致编译器无法实例化该模板,从而报错。

修改方案

方案1:使用标准库的std::conditional

直接删除自定义的conditional前向声明,将or_模板中的conditional替换为std::conditional即可,C++14完全支持std::conditional:

#include <type_traits>
#include <iostream>
#include <vector>
#include <list>

template <typename T>
struct IsVector : public std::false_type {};

template <typename T>
struct IsVector<std::vector<T>> : public std::true_type {};

template <typename T>
struct IsList : public std::false_type {};

template <typename T>
struct IsList<std::list<T>> : public std::true_type {};

// 修改or_模板,使用std::conditional
template <typename...>
struct or_;

template <>
struct or_<> : public std::false_type {};

template <typename _B1>
struct or_<_B1> : public _B1 {};

template <typename _B1, typename _B2>
struct or_<_B1, _B2> : public std::conditional<_B1::value, _B1, _B2>::type {};

template <typename _B1, typename _B2, typename _B3, typename... _Bn>
struct or_<_B1, _B2, _B3, _Bn...> : public std::conditional<_B1::value, _B1, or_<_B2, _B3, _Bn...>>::type {};
// ---

template <typename T>
struct IsVectorOrList : public or_<IsVector<T>, IsList<T>>::type {};

template <typename T>
// 现在可以正常使用IsVectorOrList了
typename std::enable_if<IsVectorOrList<T>::value, void>::type
foo(const T& list)
{
    for (const auto& item : list)
    {
        std::cout << item << std::endl;
    }
}


int main()
{
    foo(std::vector<int>{17, 42});
    foo(std::list<float>{1.0, 2.71, 3.14});
}

方案2:补全自定义conditional的实现

如果一定要自己实现conditional,添加完整定义:

template <bool B, typename T, typename F>
struct conditional { typedef T type; };

template <typename T, typename F>
struct conditional<false, T, F> { typedef F type; };

将这段代码放在or_模板之前即可。

说明

两种方案都能解决问题,优先推荐方案1,直接复用标准库组件更可靠,避免重复造轮子。

内容的提问来源于stack exchange,提问作者bselu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:37:03