Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class type non-type template parameter initialization does not compile

I was under the impression that the following should become valid code under the new C++20 standard:

struct Foo
{
  int a, b;
};

template<Foo>
struct Bar
{};

Bar<{.a=1, .b=2}> bar;

Yet, gcc 10.2.0, with -std=c++20 set complains: could not convert ‘{1, 2}’ from ‘<brace-enclosed initializer list>’ to ‘Foo’ and Clang cannot compile this snippet either. Can someone point out why it is not well formed?

like image 553
Peter Avatar asked Nov 05 '20 18:11

Peter


1 Answers

This template-argument

{.a=1, .b=2}

is not allowed according to the grammar for a template-argument which only allows the following constructs:

template-argument:

constant-expression

type-id

id-expression

A brace-init list is not any of the above constructs, it's actually an initializer and so it cannot be used as a template-argument.

You can be explicit about the type of the object that you use as the template-argument:

Bar<Foo{.a=1, .b=2}> bar;

and this will work, since this is a constant-expression.

like image 70
cigien Avatar answered Sep 25 '22 20:09

cigien