Он использует конструктор по умолчанию, потому что инициализация списка с помощью {}
всегда должна быть краткой формой инициализации значения, игнорируя другие конструкторы, даже если они являются конструкторами списка инициализатора.
Есть ли в любом случае различать следующие две конструкции: ...
X()
- это всегда инициализация значения, а X{}
- только инициализация значения, если X
имеет конструктор по умолчанию. Если это агрегат, то X{}
- это агрегатная инициализация (рекурсивная инициализация членов X
с помощью {}
). Если в нем есть только конструкторы списка инициализаторов и нет конструкторов по умолчанию, то X()
недопустим и X{}
может быть допустимым
struct A { A(initializer_list<int>); };
A a = A{}; // valid
A b = A(); // invalid
По существу, то, что делает X{}
, зависит от того, что является X
. Но X()
всегда значение инициализируется.
... или вернуть X (); против возврата {};
Нечто упомянутое ... В return {}
цель инициализируется при копировании списка, а в return X();
сначала выполняется прямая инициализация X
. Но даже при том, что он инициализирован списком копирования, он может использовать конструктор по умолчанию explicit
, потому что инициализация значения не заботится о explicit
. Однако, когда вы делаете return {}
и пытаетесь использовать явный конструктор не по умолчанию, вы выдаете ошибку
struct A {
explicit A(initializer_list<int>);
};
A f() { return {}; } // error!
struct B {
explicit B();
};
B g() { return {}; } // OK