理解对象初始化
Understanding object 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);
}
输出:
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) };
}
输出:
A(2)
A(3)
A()
你不能解释一下这个区别吗?
N4527§8.5 [dcl.init]
17初始化式的语义如下:目标类型是对象或引用的类型初始化后,源类型是初始化表达式的类型。如果初始化式不是单个的(可能是表达式,则源类型未定义。
-(17.1)如果初始化式是(未加括号的)大括号初始化列表,则对象或引用被列表初始化(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++有一个bug。Clang正确拒绝你的代码
相关文章:
- C++使用整数的压缩数组初始化对象
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- 在 c++ 中初始化对象
- C++ 手动分配和初始化对象
- 使用运算符"="在C++中用值初始化对象
- 当我不需要数据库中的所有值时,如何部分初始化 c++ 对象?
- 如何初始化对象数组?
- 在C++中使用默认构造函数初始化对象的不同方法
- 使用默认构造函数初始化对象的不同方法
- 是否可以在编译时初始化对象的 C 样式函数指针,以便它调用对象的成员函数?
- 如何在线程中初始化对象,然后在其他地方使用它?
- 在没有默认构造函数时使用垃圾数据初始化对象
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- 初始化对象以在 C++08 中作为参数传递的首选语法是什么?
- 在 c++ 中复制对未初始化对象的引用
- 在成员变量在另一个文件中发生更改后,调用与初始化对象分开的函数
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- 当您通过分配初始化C 对象时会发生什么
- 获取未初始化对象成员的地址是否定义良好?