繁体   English   中英

为什么显式声明的构造函数会阻止使用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
}

有一个很好的理由,为什么显式声明的默认构造函数会导致错误? 我认为初始化列表的位置是为了避免程序员编写像第二个构造函数这样繁琐的代码。

聚合初始化 - 顾名思义 - 仅适用于聚合。 向类中添加一个非平凡的构造函数使其成为非聚合的。 [dcl.init.list] / 3:

列表初始化对象或类型T的引用定义如下:
- 如果初始化列表没有元素且T是具有默认构造函数的类类型,则对象将进行值初始化。
- 否则,如果T是聚合,则执行聚合初始化(8.5.1)。
- 除此以外, […]

聚合是一个数组或类(第9条), 没有用户提供的构造函数 (12.1),[...]
当初始化程序列表初始化聚合时,如8.5.4中所述,初始化程序列表的元素将作为聚合成员的初始化程序,增加下标或成员顺序。

一旦您的类不再是聚合,list-initialization将查找要调用的构造函数,而不是要初始化的成员。

原因很简单:如果一个类有非平凡的构造函数,那么有效初始化该类类型的对象的唯一方法是调用该对象的一个​​构造函数。 在没有相应构造函数的情况下初始化类对象将是一个毁灭性的设计失败。

假设它是显式定义的构造函数,它将初始化结构。 因此,当使用初始化列表时,编译器会搜索适当的构造函数。 正如您已经指出的那样,如果要声明一个带有两个int类型参数的构造函数,那么您可以使用初始化列表来初始化结构的数据成员,因为将调用此构造函数。 或者你可以提供一个构造函数,它有一个std :: initializer_list类型的参数。

例如

S( std::initializer_list<int> );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM