C++模板元编程实现type成员类型检测结果不符合预期问题求解
问题原因
你的代码核心错误是模板偏特化的参数类型和主模板默认实参不匹配,导致偏特化分支永远不会被编译器选中:
- 主模板的第二个模板参数默认值为
void,但你在偏特化分支中将std::enable_if_t的第二个参数指定为T。当你传入的测试类型T不是void时,偏特化推导得到的第二个参数类型和主模板默认的void完全不匹配,编译器只会选择继承std::false_type的默认分支,所以所有测试结果都为false。 - 额外的冗余问题:你用
std::is_same_v<typename T::type, typename T::type>做判断没有必要,只要typename T::type是合法表达式就可以满足你的检测需求,不需要判断类型和自身相等。
修正方案
方案1:对齐enable_if_t的返回类型和主模板默认值
把std::enable_if_t的第二个参数改为void,和主模板默认的void匹配即可:
// 分支2修改后 template <typename T> struct has_type< T, std::enable_if_t<std::is_same_v<typename T::type, typename T::type>, void> > : std::true_type {};
方案2:用void_t简化写法(推荐)
C++17及以上可以直接用std::void_t,它可以把任意合法的类型序列转换为void,专门用于这类SFINAE检测场景,代码更简洁易读:
// 分支2修改为 template <typename T> struct has_type<T, std::void_t<typename T::type>> : std::true_type {};
如果是C++11环境,可以自己实现void_t:
template<typename...> using void_t = void;
修改后运行测试,has_type<with_type>::value会输出1,has_type<without_type>::value输出0,符合预期。
内容的提问来源于stack exchange,提问作者Fausturs
相关产品推荐
相关产品推荐

