了解对象初始化

时间:2015-09-29 04:39:55

标签: c++ initialization

我在初始化数组时忘了写大括号:

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);
}

DEMO

输出:

A(2)
A(2)
A(2)
A(3)

这是正确的,就我而言。 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) };
}

DEMO

输出:

A(2)
A(3)
A()

难道你不能解释这种差异吗?

1 个答案:

答案 0 :(得分:4)

N4527§8.5[dcl.init]

  

17初始化器的语义如下。 目标类型是对象或引用的类型   初始化,源类型是初始化表达式的类型。如果初始化器不是单个(可能是   括号内表达式,源类型未定义。

     

- (17.1)如果初始化器是(非括号的)braced-init-list,则对象或引用是列表初始化的(8.5.4)。

     

- (17.2)如果目的地类型是参考类型,请参见8.5.3。

     

- (17.3)如果目标类型是字符数组,则为char16_t数组,char32_t数组或   wchar_t数组,初始值设定项是字符串文字,见8.5.2。

     

- (17.4)如果初始值设定项为(),则对象进行值初始化。

     

- (17.5)否则,如果目标类型是数组,则程序格式错误。

     

[省略其他不相关的子弹]

A a[3] = A(2)属于(17.5),所以你的程序格式不正确。显然g++ has a bug in this caseclang correctly rejects your code