C++11: 列表初始化中使用()还是{}?

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

否则,它将使用聚合初始化。
现在,这里 是一个使用 vector 的示例,它具有从 size_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的构造函数不同?

1个回答

3
因为在所有构造函数中, initializer_list 的重载被强烈优先选择。 根据[over.match.list]: 当非聚合类类型 T 的对象进行列表初始化 (8.5.4) 时,重载决议会分两个阶段来选择构造函数: (1.1) - 首先,候选函数是类 T初始化器列表构造函数(8.5.4),参数列表由初始化器列表作为单个参数组成。 (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)。


谢谢。现在我发现在声明中,()不能工作,只有{}可以工作。 - user1914692
1
@user1914692 请不要更改您的问题以提出另一个问题。如果您有新的问题,请提出新的问题。 - Barry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接