gcc 类类型非类型模板参数初始化不编译[重复]

e4yzc0pl  于 2024-01-08  发布在  其他
关注(0)|答案(2)|浏览(118)

此问题在此处已有答案

Can you use a braced-init-list as a (default) template argument?(2个答案)
21天前关闭
编辑:这个问题已经三年了,怎么会是昨天问的另一个问题的重复呢?
我的印象是,以下代码应该成为新C++20标准下的有效代码:

  1. struct Foo
  2. {
  3. int a, b;
  4. };
  5. template<Foo>
  6. struct Bar
  7. {};
  8. Bar<{.a=1, .b=2}> bar;

字符串
然而,gcc 10.2.0,设置了-std=c++20,抱怨说:could not convert ‘{1, 2}’ from ‘<brace-enclosed initializer list>’ to ‘Foo’和Clang也不能编译这个片段。有人能指出为什么它格式不好吗?

p8h8hvxi

p8h8hvxi1#

这个模板参数

  1. {.a=1, .b=2}

字符串
根据只允许以下结构的模板参数的语法,不允许:
template-argument:
constant-expression
类型id
ID表达式
大括号初始化列表不是上面的任何一个结构,它实际上是一个初始化器,因此不能用作模板参数。
你可以明确地指出你用作template-argument的对象的类型:

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


这是可行的,因为这是一个常数表达式。

展开查看全部
n3ipq98p

n3ipq98p2#

这是一个C语法的东西。模板参数使用的东西必须是类型id,id名称,或常量表达式。
花括号初始化列表不是任何类型的表达式,它们只能在语法上出现在少数地方,特别是那些用于初始化对象或变量的地方。
在过去,这并不重要,因为没有太多的理由使用花括号初始化列表来初始化几个有效的NTTP。显然,这已经改变了,所以这是一个疏忽。但这是C
20标准所说的。

相关问题