The following does not compile on GCC 9.1 (which supports class non-type template parameters)
struct S { int i; };
template<S s>
struct T {};
int main()
{
T<{0}> x{};
}
The compiler reports error: could not convert '{0}' from '<brace-enclosed initializer list>' to 'S'
despite the template argument s
being of concrete type S
.
T<S{0}> x{};
works as expected, but will C++2a allow the concrete type name S
to be omitted, as is the case in other parts of the language?
will C++2a allow the concrete type name S to be omitted?
No.
[temp.arg.nontype]/2
A template-argument for a non-type template-parameter shall be a converted constant expression (
[expr.const]
) of the type of the template-parameter.
In T<{0}>
, {0}
is not an S
: it is not an expression of the type of the template-parameter (S
). {0}
would be an initializer list (in a context where it would be allowed).
Bonus:
[dcl.init.list]/4
List-initialization can occur in direct-initialization or copy-initialization contexts; list-initialization in a direct-initialization context is called direct-list-initialization and list-initialization in a copy-initialization context is called copy-list-initialization.
No initialization occur for template-arguments (unless when it does, see [temp.arg.nontype]/1
).
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