c++构造对象时圆括号和大括号有什么区别

What's the difference between parentheses and braces in c++ when constructing objects

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

我认为 {} 应该只支持 initializer_list 或数组,但是当我 运行 下面的截图时,我感到困惑。

#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 类型。但实际结果编译完美无误。

我错过了什么?

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

S s2{12}; 被视为 list initialization (C++11 起); S 不是聚合类型,也不是 std::initializer_list,并且没有采用 std::initializer_list 的构造函数,则

If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed.

你认为

I think {} is only can be used for an array or initializer_list type.

这不是真的。列表初始化的效果是,例如如果S是聚合类型,则进行聚合初始化;如果 Sstd::initializer_list 的特化,则它被初始化为 std::initializer_list;如果S有一个构造函数采用std::initializer_list,那么它会被优先用于初始化。您可以参考 the page 链接以获得更准确的详细信息。

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