初始化C ++ 2a类非类型模板参数时是否可以省略类型名称?

inv*_*xed 9 c++ c++20

以下内容无法在GCC 9.1(支持类非类型模板参数)上编译

struct S { int i; };

template<S s>
struct T {};

int main()
{
    T<{0}> x{};
}
Run Code Online (Sandbox Code Playgroud)

error: could not convert '{0}' from '<brace-enclosed initializer list>' to 'S'尽管template参数s为具体类型,但编译器仍会报告S

T<S{0}> x{};
Run Code Online (Sandbox Code Playgroud)

可以按预期工作,但是C ++ 2a S是否可以像在该语言的其他部分一样允许省略具体的类型名称?

YSC*_*YSC 8

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

列表初始化可以在直接初始化或复制初始化上下文中进行;在直接初始化上下文中的列表初始化称为直接列表初始化,而在复制初始化上下文中的列表初始化称为复制列表初始化。

模板参数不会发生初始化(除非进行初始化,请参见[temp.arg.nontype]/1)。

  • 我的意思是肯定的,但是为什么不只说语法不允许将括号列表用作模板参数:) (3认同)