C++ 类类型非类型模板参数初始化未编译

C++ 类类型非类型模板参数初始化未编译,c++,gcc,language-lawyer,c++20,C++,Gcc,Language Lawyer,C++20,我的印象是,在新的C++20标准下,以下代码应该成为有效代码: struct Foo { int a, b; }; template<Foo> struct Bar {}; Bar<{.a=1, .b=2}> bar; structfoo { INTA,b; }; 模板 结构条 {}; 酒吧; 然而,GCC10.2.0和-std=c++20集抱怨:无法将“{1,2}”从“”转换为“Foo”,而Clang也无法编译此代码段。有人能指出为什么格式不好吗?这个模板参

我的印象是,在新的C++20标准下,以下代码应该成为有效代码:

struct Foo
{
  int a, b;
};

template<Foo>
struct Bar
{};

Bar<{.a=1, .b=2}> bar;
structfoo
{
INTA,b;
};
模板
结构条
{};
酒吧;
然而,
GCC10.2.0
-std=c++20
集抱怨:
无法将“{1,2}”从“”转换为“Foo”
,而Clang也无法编译此代码段。有人能指出为什么格式不好吗?

这个模板参数

{.a=1, .b=2}
根据只允许以下构造的语法,不允许:

模板参数:

Bar<Foo{.a=1, .b=2}> bar;
恒定表达式

类型id

id表达式

大括号初始化列表不是上述任何构造,它实际上是一个,因此不能用作模板参数

可以明确说明用作模板参数的对象的类型:

Bar<Foo{.a=1, .b=2}> bar;
Bar;
这将起作用,因为这是一个常量表达式


感谢@尼科拉和@阿蒂尔,我把它指出来。

< P>这是一个C++语法的东西。用于模板参数的内容必须是

大括号的init列表不是任何类型的表达式。它们只能在语法上出现在少数地方,特别是用于初始化对象或变量的地方


在过去,它并不真正相关,因为没有太多的理由使用大括号的init列表来初始化少数有效的NTTP。很明显,这已经改变了,所以这是一个疏忽。但是这就是C++20标准所说的。

确实可以编译,但我不明白为什么编译器不能在这里进行推导,并且在
bar({.a=1,.b=2})
上做得非常好,因为
bar
是一个接受
Foo
类型参数的函数。你能解释一下为什么这里不可能进行推断吗?看看是否
auto&&ref={.a=1,.b=2}编译。模板参数类型推断和
自动&
类型推断遵循相同的规则。我想它也不会编译,你会更容易弄明白为什么会这样。@TanveerBadar我不相信。在OP的情况下,没有什么可以推断的,没有未知的类型。看起来它只是C++语法,不允许它:模板模板是什么,而<代码>支撑的init列表< /C>是一个,不是一个常量表达式。预计在几个月内(加上或减去实现时间),它将被修复,可能即使使用
-std=c++20
。您可以将标记添加到这个中吗?可能会吸引更多能够引用《标准》章节的合格人员。