Как работает эта подобная списку инициализация?

Я знаю о нескольких типах инициализации в C++ и недавно узнал, почему альтернативы">предпочтительна инициализация списка. Но как насчет этого кода? демонстрация

#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

Это похоже на некоторую инициализацию списка, смешанную с вызовом конструктора с использованием круглых скобок. Поэтому я подумал, что он создаст временный экземпляр A из {1, "2"}, а затем вызовет конструктор-копию. Но этого не происходит. Вместо этого он ведет себя как инициализация списка. Может быть, меня просто смущает синтаксис, и это является инициализацией списка?

Если да, то как здесь работает синтаксис? Если нет, то что это за инициализация?


person churill    schedule 07.05.2020    source источник
comment
Похоже на некую инициализацию списка, смешанную с вызовом конструктора с использованием круглых скобок. Поэтому я подумал, что он создаст временный экземпляр A из {1, 2}, а затем вызовет конструктор копирования. Я согласен, но вы забыли о copy-elision. ;-)   -  person Scheff's Cat    schedule 07.05.2020


Ответы (2)


Поэтому я подумал, что он создаст временный экземпляр A из {1, "2"}, а затем вызовет конструктор копирования.

Ты прав. Здесь объект a инициализируется через конструктор A::A(int x, std::string y) напрямую из-за копирования.

Вы можете скомпилировать с опцией -fno-elide-constructors (с режимом pre-C++17, так как C++17 такое исключение копирования гарантировано), вы получите

normal
copy

ПРЯМОЙ ЭФИР

person songyuanyao    schedule 07.05.2020

A a({1, "2"}); на самом деле copy-list-initialization, где braced-init-list используется вместо аргумента конструктора.

person NutCracker    schedule 07.05.2020