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

Ara*_*raK 12 c++ c++11

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

要初始化结构:

struct myclass
{
    myclass(int px, int py) : x(px), y(py) {}
private:
    int x, y;
};
...
myclass object{0, 0};
Run Code Online (Sandbox Code Playgroud)

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

vector<double> numbers{10};
Run Code Online (Sandbox Code Playgroud)

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

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );
Run Code Online (Sandbox Code Playgroud)

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

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

vector<double> numbers(10); // 10 elements instead of just one element with value=10
Run Code Online (Sandbox Code Playgroud)

Ara*_*raK 9

我在标准文档(最新草案)中找到了答案.希望,我会尝试解释我的理解.

首先,如果一个类定义了一个初始化列表构造函数,那么只要合适,它就会被使用:

§8.5.4(第203页)

初始化列表构造函数优于列表初始化(13.3.1.7)中的其他构造函数.

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

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

基本上,想象std::vector没有初始化列表构造函数,然后以下将创建一个包含10个元素的向量:

std::vector<int> numbers{10};
Run Code Online (Sandbox Code Playgroud)

通过添加初始化列表构造函数,由于{}语法原因,编译器会优先于其他构造函数.会发生这种情况的原因初始化列表中的元素{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.
Run Code Online (Sandbox Code Playgroud)


Tim*_*ter 2

看看这个:

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

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

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