为什么显式声明的构造函数会使用C++11初始化列表阻止成员初始化
Why does an explicitly declared constructor prevent member initialisation with a C++ 11 initialisation list?
我想用这样的初始化列表初始化一个结构:
struct S
{
int a;
int b;
// S() : a(0), b(0){} // uncommenting will cause compile error:
// error C2440: 'initializing' : cannot convert from 'initializer-list' to 'S'
// S(int aArg, int bArg) : a(aArg), b(bArg) {} // adding this removes the error
}
int main()
{
S s{1,2}; // initialise with list
}
为什么显式声明的默认构造函数会导致错误,有充分的理由吗?我认为引入初始化列表是为了避免程序员编写像第二个构造函数那样乏味的代码。
类型T的对象或引用的列表初始化定义为如下:
-如果初始值设定项列表没有元素,并且T是一个类类型,则对象被值初始化
--否则,如果T是聚合,则执行聚合初始化(8.5.1).
--否则,[…]
和
聚合是一个数组或类(第9条),其中没有提供用户构造函数(12.1),[…]
当聚合由初始化器列表初始化时,如8.5.4所述,初始化器列表的元素以递增下标或成员顺序作为聚合成员的初始值设定项。
一旦您的类不再是聚合,列表初始化将查找要调用的构造函数,而不是要初始化的成员。
原因很简单:如果一个类有非平凡的构造函数,有效初始化该类类型的对象的唯一方法是调用该对象的构造函数之一。在没有相应构造函数的情况下初始化类对象将是一个毁灭性的设计失败。
应该是显式定义的构造函数来初始化结构。因此,当使用初始值设定项列表时,编译器会搜索适当的构造函数。正如您自己已经指出的那样,如果用两个int类型的参数声明一个构造函数,那么您可以使用初始值设定项列表来初始化结构的数据成员,因为这个构造函数将被调用。或者,您可以提供一个构造函数,该构造函数有一个std::initializer_list类型的参数。
例如
S( std::initializer_list<int> );
相关文章:
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 在 C++11 及更高版本中,有没有办法初始化初始值设定项列表中的向量?
- C++11 中的混合列表初始化
- 在 C++11 中轻松初始化模板类的静态成员,没有 clang 警告
- 为什么静态数据成员不能在c++11中的类中初始化
- C++11 默认类成员初始化与初始值设定项列表同时
- C++11默认初始化/值初始化/直接初始化
- C++11 整数初始化
- C++11 成员类初始化顺序
- 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此大括号初始化列表代码
- 为什么编译器在试图初始化具有C 11样式的对象数组时隐含删除构造函数
- 如何在一行中初始化 C++11 中的 n 个相等元素的向量
- 仅初始化c++11元组的第一个参数
- 初始化 C++11 数组的最佳方法,主要是标识映射
- 我们什么时候应该使用括号 ( ) 与初始值设定项 { } 语法来初始化 C++11 中的对象
- 正在初始化C++11中要求为prvalue的表达式
- 从if语句中初始化C++11线程
- 初始化directX 11时出现未处理的异常错误
- 如何使用常规构造函数模式初始化 C++ 11 标准容器
- 如何正确初始化c++ 11 std::seed_seq