Читать «Эффективный и современный С++. 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 вводит унифицированную инициализацию (uniform initialization): единый синтаксис инициализации, который может, как минимум концептуально, использоваться везде и выражать все. Он основан на фигурных скобках, и по этой причине я лично предпочитаю термин “фигурная инициализация” (braced initialization). Унифицированная инициализация — это идея. Фигурная инициализация — это синтаксическая конструкция.

Фигурная инициализация позволяет выразить то, что было невозможно выразить ранее. С помощью фигурных скобок легко указать начальное содержимое контейнера: