template<bool b = 2> void foo(void) {}
template void foo();
template<unsigned char n = 258> void bar(void) {}
template void bar();
GCC instantiates foo< true> and bar<2>; Clang rejects both with "error: non-type template argument evaluates to 2, which cannot be narrowed to type 'bool' [-Wc++11-narrowing]".
Is the above code valid? Is this a bug in one of them?
Versions used: Clang 3.8.0-2ubuntu4, GCC 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2)
This is gcc bug 57891 and 60715.
From [temp.arg.nontype]:
A template-argument for a non-type template-parameter shall be a converted constant expression (5.20) of the type of the template-parameter.
From [expr.const]:
A converted constant expression of type T is an expression, implicitly converted to type T, where the converted expression is a constant expression and the implicit conversion sequence contains only [...] integral conversions (4.7) other than narrowing conversions (8.5.4),
From [dcl.init.list]:
A narrowing conversion is an implicit conversion [...] from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
Narrowing conversions (e.g. 2
to bool
or 258
to char
) are ill-formed for template non-type parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With