C++11 有一个新的初始化语法。这是 Scott Myers 在他的《Effective Modern C++》一书中所写的:
class Widget {
public:
Widget(); // default ctor
Widget(std::initializer_list<int> il); // std::initializer_list ctor
… // no implicit conversion funcs
};
Widget w1; // calls default ctor
Widget w2{}; // also calls default ctor
Widget w3(); // most vexing parse! declares a function!
Widget w4({}); // calls std::initializer_list ctor with empty list
Widget w5{{}}; // ditto
如果我们以他的例子为例,去掉多余的部分,并将 print 添加到构造函数Widget
中,事实证明Widget w4({});
这Widget w5{{}};
不是一回事:
#include <iostream>
#include <initializer_list>
class Widget{
public:
Widget(){
}
Widget(std::initializer_list<int> l){
std::cout << "l.size = " << l.size() << std::endl;
}
};
int main(){
Widget w4({}); //l.size = 0
Widget w5{{}}; //l.size = 1
}
我有两个问题:
- 斯科特在骗我们吗?
- 到底发生了什么?
按照标准,它优先于
list-initialization
.这是
direct-initialization
. 初始化程序是空的std::initializer_list
。已经是了
list-initialization
。在这种情况下direct-list-initialization
。如果初始化列表为空,则选择默认构造函数。如果初始化列表不为空,则分两个阶段选择构造函数:
我们开始“手动”搜索合适的构造函数的第一阶段。
在第一阶段,所有参数都被视为一个
initializer list
。如果我们将初始化程序中的括号视为创建 std::initializer_list,是否可以
std::initializer_list<int>
通过传递它来创建{}
?是的你可以就是这样,找到了合适的构造函数。
也就是说,在我们的例子中
或更多示例:
我试图尽可能简单地解释,因此,“用我自己的话”的表述可能并不完全准确。