函数参数能否作为模板实参?编译器分歧正确性判定咨询
编译器行为正确性分析
这段代码中,Clang的处理是正确的,GCC与MSVC的判定有误,原因如下:
核心规则:非类型模板参数的实参类型匹配要求
根据C++标准中[temp.arg.nontype]条款的规定,除少数特殊例外(比如std::nullptr_t可转换为指针类型),非类型模板参数的实参类型必须与模板参数的类型完全匹配。
在代码中:
- 模板
A的参数是bool类型的非类型模板参数; foo函数的参数b类型是std::integral_constant<bool, true>(即std::true_type),属于类类型对象。
当尝试写typename A<b>时,b的类类型与模板A要求的bool类型完全不匹配——即使std::true_type拥有可隐式转换为bool的constexpr转换函数,标准也不允许通过隐式转换来适配非类型模板参数的类型要求,因此这个类型要求是非法的,foo应返回false。
合法写法示例
若要让代码符合标准,需要显式将b转换为bool类型的常量表达式,比如:
return requires { typename A<static_cast<bool>(b)>; }; // 或利用std::integral_constant的成员 return requires { typename A<b.value>; }; return requires { typename A<b()>; };
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

