这个类似列表的初始化是如何工作的?

How does this list-like initialization work?

我知道 C++ 中的几种初始化类型,最近才知道为什么 list initialization should be preferred. But what about this code? live demo

#include <iostream>
#include <string>

class A {
public:
    A(int x, std::string y) { std::cout << "normal\n"; }

    A(const A& obj) { std::cout << "copy\n"; }
};

int main(){
    A a({1, "2"}); // strange initialization
}

打印:

normal

它看起来像某种列表初始化与使用括号的构造函数调用混合在一起。所以我认为它会从 {1, "2"} 创建一个 A 的临时实例,然后调用复制构造函数。但那不会发生。相反,它的行为类似于列表初始化。也许我只是对语法感到困惑,它 列表初始化?

如果是,这里的语法是如何工作的?如果不是,这是什么初始化?

So I thought it would create a temporary instance of A from {1, "2"} and then call the copy-constructor.

你是对的。这里对象 a 直接通过构造函数 A::A(int x, std::string y) 初始化,因为 copy elision.

您可以使用 -fno-elide-constructors 选项进行编译(使用 C++17 之前的模式,因为 C++17 保证了这种复制省略),您将得到

normal
copy

LIVE

A a({1, "2"}); 实际上是 copy-list-initialization,其中 braced-init-list 用于代替构造函数参数。