C ++ 0x中的统一初始化,何时使用()而不是{}?

时间:2009-12-08 00:18:21

标签: c++ c++11

是否有经验法则决定何时使用旧语法 () 而不是新语法 {}

初始化结构:

struct myclass
{
    myclass(int px, int py) : x(px), y(py) {}
private:
    int x, y;
};
...
myclass object{0, 0};

现在以vector为例,它有许多构造函数。每当我做以下事情时:

vector<double> numbers{10};

我得到 1 元素的向量,而不是带有 10 元素的元素,因为其中一个构造函数是:

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );

我怀疑每当一个类定义一个initializer list构造函数时,就像一个向量一样,它会被 {} 语法调用。

所以,我正在思考的是正确的。 ie 只有当一个类定义一个初始化列表构造函数来调用另一个构造函数时,我才能恢复到旧的语法吗?,例如纠正上述代码:

vector<double> numbers(10); // 10 elements instead of just one element with value=10

2 个答案:

答案 0 :(得分:9)

我在标准文档(latest draft)中找到了答案。希望,我会尝试解释我的理解。

首先,如果一个类定义了一个初始化列表构造函数,那么在适当的时候使用它:

  

§8.5.4(第203页)

     

初始化列表构造函数是   比其他建设者更受青睐   list-initialization(13.3.1.7)。

我认为这是一个很棒的功能,消除了与非统一风格相关的头痛:)

无论如何,唯一的问题(我的问题是关于)如果你设计一个没有初始化构造函数的类,那么你以后添加它可能会得到令人惊讶的结果。

基本上,假设std::vector没有初始化列表构造函数,那么下面将创建一个包含10个元素的向量:

std::vector<int> numbers{10};

通过添加初始化列表构造函数,由于{}语法,编译器会优先于其他构造函数。发生此行为是因为使用init-list构造函数接受了init-list {10} 的元素。如果没有可接受的转换,则应使用任何其他构造函数,例如:

std::vector<string> vec{10};
// a vector of 10 elements.
// the usual constructor got used because "{0}"
// is not accepted as an init-list of type string.

答案 1 :(得分:2)

看看这个:

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=453&rll=1

在变量上使用{}样式的初始值设定项没有直接映射到类的任何构造函数的初始化列表。可以添加/删除/修改那些构造函数初始化列表,而不会破坏现有的调用者。

基本上,容器的不同行为是特殊的,并且需要该容器中的特殊代码,特别是采用std::initializer_list的构造函数。对于POD和简单对象,您可以互换使用{}()