C ++:如何通过初始化列表进行构造?

C++: how is construction by initialization list done?

C++ 允许实例化 class,通过初始化列表设置 public 成员的值,如下例所示 b1:

class B {
public:
    int i;
    std::string str;
}; 

B b1{ 42,"foo" };
B b2();

;但是,如果我提供构造函数

B(int k)    {   }

,它不会编译。

那么,幕后发生了什么? 是不是当没有提供构造函数时,编译器会提供一个?但是它怎么能提供一个初始化列表呢?我认为它只会提供一个不接受任何输入的 "blank" 构造函数,如 b2 的示例所示。还是两者都提供?

But how could it provide one with initialization list?

不,不会。

注意执行list initialization B b1{ 42,"foo" };, aggregate initialization

If T is an aggregate type, aggregate initialization is performed.

B 一个aggregate type,

An aggregate is one of the following types:

array type
class type (typically, struct or union), that has 

    no private or protected non-static data members
    no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)
    no virtual, private, or protected base classes
    no virtual member functions

这就是 B b1{ 42,"foo" }; 运作良好的原因。

并且如果你提供了一个用户定义的构造函数,B变成了非聚合类型,那么聚合初始化将不再起作用。在这种情况下,您只能像 B b1{42};B b2(42); 一样初始化 B,这将调用适当的构造函数。

顺便说一句:在提供了一个用户定义的构造函数(带一个参数)之后,implicitly-declared default constructor 将不会被编译器再次声明。这意味着 B b2;B b2{}; 将不再有效。

BTW2:B b2(); 可能是一个函数声明。参见 Most vexing parse