我在初始化数组时忘了写大括号:
struct A
{
A() { std::cout << "A()" << std::endl; }
A(int a) { std::cout << "A(" << a << ")" << std::endl; }
};
int main()
{
A a[3] = A(2), A(3);
}
Run Code Online (Sandbox Code Playgroud)
输出:
A(2)
A(2)
A(2)
A(3)
Run Code Online (Sandbox Code Playgroud)
就我而言,这是正确的.N4257::12.6.1/2:
对于任何聚合,可以在初始化列表中省略大括号,即使聚合具有具有用户定义类型转换的类类型的成员也是如此
但支持初始化具有不同的副作用:
struct A
{
A() { std::cout << "A()" << std::endl; }
A(int a) { std::cout << "A(" << a << ")" << std::endl; }
};
int main()
{
A a[3] = { A(2), A(3) };
}
Run Code Online (Sandbox Code Playgroud)
输出:
A(2)
A(3)
A()
Run Code Online (Sandbox Code Playgroud)
你不能解释这个区别吗?
N4527 \xc2\xa7 8.5 [dcl.init]
\n\n\n\n\n17 初始化器的语义如下。目标类型是正在初始化的对象或引用的类型,源类型是初始化表达式的类型。如果初始值设定项不是单个(可能\n 带括号的)表达式,则源类型不会被 de\xef\xac\x81ned。
\n\n\xe2\x80\x94 (17.1) 如果初始化器是一个(非括号的)大括号初始化列表,则对象或引用是列表初始化的 (8.5.4)。
\n\n\xe2\x80\x94 (17.2) 如果目标类型是引用类型,请参见 8.5.3。
\n\n\xe2\x80\x94 (17.3) 如果目标类型是字符数组、char16_t 数组、char32_t 数组或\n wchar_t 数组,并且初始值设定项是字符串文字,请参阅 8.5.2。
\n\n\xe2\x80\x94 (17.4) 如果初始化器是 (),则对象是值初始化的。
\n\n\xe2\x80\x94 (17.5) 否则,如果目标类型是数组,则程序格式错误。
\n\n[其他无关项目省略]
\n
A a[3] = A(2)落入(17.5),所以你的程序是错误的。显然g++ 在这种情况下有一个错误。clang 正确地拒绝了您的代码。