3

我指的是“工作草案 N3337 ”,据说与已发布的 C++11 标准最相似

如果有可匹配的构造函数,则调用构造函数。

Example (p200):
struct S {
    // no initializer-list constructors
    S(int, double, double); // #1
    S(); // #2
    // ...
};

S s1 = { 1, 2, 3.0 }; // OK: invoke #1
S s2 { 1.0, 2, 3 }; // error: narrowing

否则,它将使用聚合初始化。

现在,是一个 using 的示例vector,它有一个显式构造函数 fromsize_t和一个initializer_list构造函数:

vector<double> v1(7);   // ok: v1 has 7 elements
vector<double> v1{7};   // ok: v1 has 1 element (with its value 7.0)

在这里我很困惑。为什么构造函数的行为与vector构造函数的行为不同S

4

1 回答 1

3

因为initializer_list重载比所有其他重载都更受欢迎。来自 [over.match.list]:

当非聚合类类型的对象T被列表初始化(8.5.4)时,重载决议分两个阶段选择构造函数:

(1.1) — 最初,候选函数是类的初始化器列表构造函数 (8.5.4),T参数列表由初始化器列表作为单个参数组成。
(1.2) — 如果没有找到可行的初始化列表构造函数,则再次执行重载决议,其中候选函数是类的所有构造函数,T参数列表由初始化列表的元素组成。

vector是一个非聚合类,它有两个相关的构造函数:

explicit vector( size_type count );           // (3)
vector( std::initializer_list<T> init,        // (7)
    const Allocator& alloc = Allocator() );

根据 [over.match.best] 中描述的顺序,由于 (7) 是一个可行的构造函数候选者,我们没有到达 (1.2) 点,其中将考虑 (3)。

于 2015-05-07T17:44:06.810 回答