我应该在构造函数初始值设定项列表中使用列表初始化吗?

Should I use list initialization in a constructor initializer list?

提问人:Luchian Grigore 提问时间:5/28/2013 最后编辑:Andy ProwlLuchian Grigore 更新时间:5/28/2013 访问量:236

问:

在 GotW #6b 第 2 部分中,我们找到了代码

class polygon {
public:
    polygon() : area{-1} {}
    //....
    double area;
};

为什么我们应该对基类型使用列表初始化而不是常用的?他们的行为是否有任何优势/情况?area(-1)

C++ C++11 初始化

评论

0赞 chris 5/28/2013
如果要调用初始值设定项列表构造函数?:)我猜它只是随着整个“统一”方面而流动。
0赞 Luchian Grigore 5/28/2013
@chris应该提到的是.areadouble
0赞 chris 5/28/2013
但是,即使它不是特定于构造函数初始化列表,它仍然被视为行为不同的情况。
1赞 taocp 5/28/2013
在他的著作《杰出的C++》中,他在第177页第43项中使用了area(-1)。
1赞 Luchian Grigore 5/28/2013
@taocp哈哈,你只知道:)

答:

7赞 Andy Prowl 5/28/2013 #1

为什么我们应该对基本类型使用列表初始化而不是常用的 area(-1)?

首先,我认为那里的信息只是 C++11 的统一初始化应该在可以使用时使用。在这种情况下,这主要是风格和品味的问题。

作者所宣扬的风格和品味,是否会成为事实上的标准,目前还很难说。我们都知道统一初始化毕竟不是那么统一。另一方面,在大多数情况下,采用它作为默认编码风格的好处是有吸引力的——语法统一性,以及诸如最令人烦恼的解析等问题消失的事实。

也就是说,当初始值设定项列表仅包含一个元素时,将从该元素初始化初始化对象 (§ 8.5.4/3)。这使得示例中的初始化等同于常规的直接初始化(但不允许缩小转换范围)。

换句话说,在您的示例中,两者都是直接初始化,它们是等效的。选择一个而不是另一个只是一个风格问题。area{-1}area(-1)

他们的行为是否有任何优势/情况?

如上所述,它们行为不同的一种情况是通过涉及缩小转换范围的初始化给出的。例如,虽然这是允许的:

int x{42};

这不是:

int y{3.14}; // ERROR! Narrowing conversion

评论

0赞 Luchian Grigore 5/28/2013
没错,列表初始化就是我的意思。事实上,我不久前问过一个问题——stackoverflow.com/questions/13267277/......——一定是我忘记了。
0赞 Andy Prowl 5/28/2013
@LuchianGrigore:好的。我编辑了答案以匹配问题的编辑
3赞 David G 5/28/2013 #2

这对标量没有影响,但作者可能符合新语法。例如,在 C++11 之前,您无法通过初始值设定项列表初始化数组,但这可以通过聚合初始化轻松实现:

struct A
{
    A() : data{1, 2, 3} // this wouldn't work as 'data(1, 2, 3)'
    {}

    int data[3];
};

同样,您也可以对向量执行相同的操作。