我一直在学习 'C++之旅',Bjarne 在构造函数中使用了 c++11 的初始化列表特性来进行成员初始化,如下所示(使用花括号):
A a;
B b;
Foo(Bar bar):
a{bar.a}, b{bar.b}
{}
然而,在 C++11 之前,这并不能编译。与旧的成员初始化列表(使用圆括号)有何区别:
Foo(Bar bar):
a(bar.a), b(bar.b)
{}
那么这两者有什么区别,何时应该优先选择其中之一?
我一直在学习 'C++之旅',Bjarne 在构造函数中使用了 c++11 的初始化列表特性来进行成员初始化,如下所示(使用花括号):
A a;
B b;
Foo(Bar bar):
a{bar.a}, b{bar.b}
{}
Foo(Bar bar):
a(bar.a), b(bar.b)
{}
那么它们有什么区别呢?
圆括号只适用于非类类型,或者具有与括号中参数数量相适应的构造函数的类型。
花括号适用于这些情况,也适用于聚合体 - 没有构造函数的简单struct
或数组类型。 因此,以下内容是可行的:
struct {
int a,b;
} aggregate;
int array[2];
Foo() : aggregate{1,2}, array{3,4} {}
最后,花括号将匹配一个取适当类型的initializer_list
参数的构造函数,而不是带有参数以匹配参数的构造函数。例如:
std::vector<int> v1;
std::vector<int> v2;
Foo() :
v1(10,2), // 10 elements with value 2
v2{10,2} // 2 elements with value 10,2
{}
什么情况下应该优先选择其中一个?在一些非常烦人的边缘情况下,可能会出现一些差异:
std::vector<int> v{3, 2}; // constructs a vector containing [3, 2]
std::vector<int> u(3, 2); // constructs a vector containing [2, 2, 2]
无论v
和u
是函数中的变量还是在初始化列表中初始化的类成员,这都是正确的。
但是,在没有std::initializer_list<T>
构造函数与接受相同数量参数的普通构造函数重叠的情况下,它们没有区别。