SFINAE场景下:如何正确使用模板结构体的模板子类?
解决C++模板参数包编译错误:
static_assert(all_of<...>::are_in<...>::value) 错误原因分析
- C2059语法错误:
any_of<Types ...>::is_same_as<Arg>中,any_of<Types...>是依赖模板参数的类型,编译器无法自动识别is_same_as是成员模板,必须用template关键字明确声明;同时is_same_as<Arg>是一个类型,需要typename关键字告知编译器这是类型而非值,否则会将<解析为小于号导致语法错误。 - 后续
value未找到、std::conditional参数无效等错误,均为test<Head>结构体未正确继承value成员引发的连锁问题。
修复代码
1. 修复is_in结构体
template <class ... Types> struct is_in { template <class Arg> struct test : typename any_of<Types ...>::template is_same_as<Arg> {}; };
通过添加typename和template关键字,明确告知编译器any_of<Types...>::is_same_as是成员模板,且其实例化结果为类型,确保test结构体正确继承到value成员。
2. 优化all_fulfill实现(可选,简化代码)
使用C++14的std::conditional_t简化递归逻辑,避免冗余的::type:
#include <type_traits> template <template <class> typename Test, typename... List> struct all_fulfill : std::false_type {}; template <template <class> typename Test, typename Head, typename... List> struct all_fulfill<Test, Head, List...> : std::conditional_t<Test<Head>::value, all_fulfill<Test, List...>, std::false_type> {}; template <template <class> typename Test> struct all_fulfill<Test> : std::true_type {};
若使用C++11,保留std::conditional并添加::type即可,无需额外修改。
3. 验证示例
假设any_of的实现符合你的工作逻辑:
template <class... Types> struct any_of { template <class Type> struct is_same_as : std::disjunction<std::is_same<Type, Types>...> {}; };
测试代码:
static_assert(all_of<int, bool>::are_in<bool, int, double>::value, "所有子类型必须存在于父类型集合中"); // 编译通过 static_assert(!all_of<int, char>::are_in<bool, int, double>::value, "Char不在父类型集合中"); // 触发断言,符合预期
内容的提问来源于stack exchange,提问作者Adrian Czupak
相关产品推荐
相关产品推荐

