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

V.W*_*.Wu 1 c++ initialization c++11

(){}构造对象之间有什么区别?

我认为{}应该只支持with initializer_list或array,但是当我在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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

我怎么了

son*_*yao 6

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

S s2{12};被当作列表初始化(从C ++ 11开始);S不是集合类型且不是std::initializer_list,并且没有构造函数采用std::initializer_list,则

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

你以为

我认为{}只能用于数组或initializer_list类型。

这不是真的。列表初始化的效果是,例如,如果S是聚合类型,则执行聚合初始化;否则,将执行聚合初始化。如果S是的专业化std::initializer_list,则将其初始化为std::initializer_list;如果S构造函数采用std::initializer_list,则首选将其用于初始化。您可以参考链接的页面以获取更精确的详细信息。

PS:S s1(12);执行直接初始化