template <bool> void f() { std::cout << "false\n"; } template <> void f<true>() { std::cout << "true\n"; } int main() { f<1>(); f<4>(); f<0>(); }
我希望int在这里被隐式转换为bool.但VC,GCC和cl the的行为却不同.
在VC上,真实的,假的和假的都是打印的,这对我来说真是怪异.
在GCC上,真实,真实和假的印刷,这是我期望的.
在cl ang ang ang ang ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;. ;.
candidate template ignored: invalid explicitly-specified argument for 1st template parameter
那么这个标准怎么说呢?非类型模板参数的隐式转换规则是什么?
解决方法
The following conversions are performed on each expression used as a non-type template-argument. If a
non-type template-argument cannot be converted to the type of the corresponding template-parameter then
the program is ill-formed.
- For a non-type template-parameter of integral or enumeration type,conversions permitted in a converted constant expression (5.19) are applied.
在§5.19中,我们学习(强调我的):
An integral constant expression is an expression of integral or unscoped enumeration type,implicitly converted
to a prvalue,where the converted expression is a core constant expression. … A converted constant expression of
typeT
is an expression,implicitly converted to a prvalue of type T,where the converted expression is a core
constant expression and the implicit conversion sequence contains only user-defined conversions,lvalue-to-rvalue
conversions (4.1),integral promotions (4.5),and integral conversions (4.7) other than narrowing conversions
(8.5.4). [ Note: such expressions may be used in new expressions (5.3.4),as case expressions (6.4.2),
as enumerator initializers if the underlying type is fixed (7.2),as array bounds (8.3.4),and as integral or
enumeration non-type template arguments (14.3). —end note ]
因此,将整数常量表达式明确禁止,因此将转换缩小(如转换为bool)在这种情况下是非类型的模板参数所必需的.这使得呼叫f 4()不成形.
我认为Clang在发布错误时是正确的,GCC和VC都不符合要求,不发布任何诊断.
[更新]这是GCC Bug #57891,看起来像是目前未分配.