Ответ 1
T a( b );
- это прямая инициализация, если она не анализирует как объявление функции, и в этом случае это объявление функции.
T a = b;
- это инициализация копии, что означает, что она работает так, как если бы временный объект строился с правой стороны, и что a
затем копируется или в С++ 11 и более поздних версиях, возможно, временный характер.
Компилятор может свободно удалять (удалять) временное + копирование/перемещение, когда это возможно, но конструктор копирования или перемещения, какой бы он ни был логически использован, должен быть доступен, а не explicit
.
Например, в С++ 03 вы не можете скопировать-инициализировать std::ostringstream
, потому что у него нет конструктора копирования. В С++ 11 вы можете скопировать инициализацию ostringstream
, если инициализатор является временным, что приводит к логической конструкции перемещения (которая, как правило, будет устранена, оптимизирована). Например, это объявление инициализации копии,
ostringstream s = ostringstream( "blah" );
& hellip; не компилируется как С++ 03, потому что в С++ 03 инициализация копии вызывает конструктор экземпляра класса, который не существует. Однако он компилируется как С++ 11, потому что в С++ 11 инициализация копии вызывает конструктор перемещения. И хотя (чтобы сохранить иллюзию потока), std::ostringstream
не может быть скопирован напрямую, его можно перемещать.
Другая такая разница: в С++ 03 только синтаксис инициализации копирования поддерживает курсивные инициализаторы фигурных скобок, которые в С++ 03 можно использовать, когда T
является агрегированным типом, таким как необработанный массив. В С++ 11 обозначение фигурных скобок было расширено и обобщено как равномерный синтаксис инициализации, поэтому его можно использовать также с прямой инициализацией. Итак, следующее объявление прямой инициализации,
int v[]{ 3, 1, 4, 1, 5, 9, 2, 6, 5, 4 };
& hellip; не компилируется как С++ 03, но компилируется как С++ 11 и более поздних версий.
Синтаксис инициализации копии =
- это исходный синтаксис инициализации из C.
И в С++ 11 и более поздних версиях из-за семантики перемещения он может использоваться в гораздо более широком диапазоне случаев, чем в С++ 03, например, с std::ostringstream
.