构造对象时,C ++中括号和花括号之间有什么区别

时间:2019-08-01 08:30:40

标签: c++ c++11 initialization

构造对象时,(){}有什么区别?

我认为{}仅应支持initializer_list或数组,但是当我在snip之下运行时,我感到困惑。

#include <iostream>
using namespace std;
struct S {
    int v=0;
    S(int l) : v(l) {
    }
};


int main()
{
    S s1(12); // statement1
    S s2{12}; // statement2
    cout << s1.v << endl;
    cout << s2.v << endl;
}

statement1是正确的,因为()是构造对象的基本语法。

我希望statement2编译失败。我认为{}仅可用于数组或initializer_list类型。但是实际结果可以完美编译而不会出错。

我错了什么?

1 个答案:

答案 0 :(得分:6)

对于S,它们具有相同的效果。两者都调用构造函数S::S(int)来初始化对象。

S s2{12};被重新命名为list initialization(自C ++ 11起); S不是集合类型,也不是std::initializer_list,并且没有构造函数采用std::initializer_list,然后

  

如果前一阶段未产生匹配项,则T的所有构造函数都将针对由braced-init-list元素组成的参数集参与重载解析,但限制为:允许缩小转换。

你以为

  

我认为{}仅可用于数组或initializer_list类型。

这不是事实。列表初始化的效果是如果S是聚合类型,则执行聚合初始化;如果Sstd::initializer_list的特化,则将其初始化为std::initializer_list;如果S的构造函数使用std::initializer_list,则首选将其用于初始化。您可以参考链接的the page以获得更详细的信息。

PS:S s1(12);执行direct initialization