Читать «Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14» онлайн - страница 39
Скотт Мейерс
3.1. Различие между {}
и ()
при создании объектов
В зависимости от вашей точки зрения выбор синтаксиса для инициализации объектов в С++11 либо очень богатый, либо запутанный и беспорядочный. Как правило, инициализирующие значения указываются с помощью круглых скобок, знака равенства или фигурных скобок:
int x(0); // Инициализатор в круглых скобках
int y = 0; // Инициализатор после "="
int z{ 0 }; // Инициализатор в фигурных скобках
Во многих случаях можно использовать знак равенства и фигурные скобки одновременно:
int z = { 0 }; // Инициализатор использует "=" и фигурные скобки
В оставшейся части данного раздела я в основном буду игнорировать синтаксис, в котором одновременно используются знак равенства и фигурные скобки, поскольку С++ обычно трактует его так же, как и версию только с фигурными скобками.
Сторонники “полного беспорядка” указывают на то, что применение знака равенства для инициализации часто сбивает с толку новичков в С++, которые считают, что имеют дело с присваиванием, хотя на самом деле это не так. Для встроенных типов наподобие int
эта разница носит чисто академический характер, но в случае пользовательских типов очень важно отличать инициализацию от присваивания, поскольку при этом вызываются различные функции:
Widget w1; // Вызов конструктора по умолчанию
Widget w2 = w1; // Не присваивание, а копирующий конструктор
w1 = w2; // Присваивание; вызов оператора operator=()
Даже при наличии нескольких синтаксисов инициализации существовали определенные ситуации, когда в С++98 не было возможности выразить желаемую инициализацию. Например, было невозможно прямо указать, что контейнер STL должен быть создан содержащим определенный набор значений (например, 1, 3 и 5).
Для устранения путаницы из-за нескольких синтаксисов инициализации и решения проблемы охвата всех сценариев инициализации С++11 вводит
Фигурная инициализация позволяет выразить то, что было невозможно выразить ранее. С помощью фигурных скобок легко указать начальное содержимое контейнера: