首先,我建议您查看 Herb Sutter 的 following talk,他在其中就该主题提出了一些建议。大括号初始化讨论从around 23:00开始。
当您谈论原始数据类型时,所有 3 种都会产生相同的结果。我个人更喜欢坚持使用旧的 int x = 0 语法,但这取决于个人喜好。
对于类类型,大括号初始化和老式构造函数初始化不是完全可以互换的。例如:
vector<int> v (100); // Creates a 100-element vector
vector<int> v {100}; // Creates a 1-element vector, holding the value 100.
这是因为std::vector 有一个构造函数,该构造函数将std::initializer_list 明确定义为其唯一参数。请记住
auto var = {1, 2};
创建一个std::initializer_list,以var 作为其标识符。
关于初始化列表的事情是,它们提供了与之前可用的内容相比的可喜变化的一致性。例如,如果你要在 C++ 中初始化一个数组,你会使用:
int arr[] = {1, 2, 3, 4};
但是,如果您想用相同的元素初始化 vector<int>,您必须:
- 先初始化上面的arr再传
arr和arr + 4
- 单独或循环创建向量和 push_back() 元素。
使用 C++11,您可以使用
vector<int> v = {1, 2, 3, 4}; // Same syntax. Nice! Note that the = is optional
大括号初始化有用的另一个例子是它为 C++ 的most vexing parse 提供了一种解决方法。从谈话中,假设我们有两个类,origin 和extents,可以传递它们的实例来构造另一个rectangle 类型的对象。以下声明:
rectangle w(origin(), extents());
不允许您使用origin 和extents 临时对象创建rectangle 对象,因为该语句被解析为函数声明。啧啧。所以通常,你必须这样做:
origin o;
extents e;
rectangle w(o, e);
通过大括号初始化,您可以动态创建它们,并且
rectangle w {origin(), extents()};
将按预期工作,即传递给以origin 对象作为其第一个参数和extents 对象作为第二个参数重载的构造函数。
规则是针对对象的,除非你有理由不这样做,否则使用大括号初始化。