Читать «Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14» онлайн - страница 40
Скотт Мейерс
std::vector<int> v{ 1, 3, 5 }; // v изначально содержит 1, 3, 5
Фигурные скобки могут также использоваться для указания значений инициализации по умолчанию для нестатических членов-данных. Эта возможность — новая в С++11 — может использоваться с синтаксисом “=
” но не с круглыми скобками:
class Widget {
…
private:
int x{ 0 }; // OK, значение x по умолчанию равно 0
int y = 0; // Тоже OK
int z(0); // Ошибка!
};
С другой стороны, некопируемые объекты (например, std::atomic
— см. раздел 7.6) могут быть инициализированы с помощью фигурных или круглых скобок, но не с помощью знака равенства:
std::atomic<int> ai1{ 0 }; // OK
std::atomic<int> ai2(0); // OK
std::atomic<int> ai3 = 0; // Ошибка!
Легко понять, почему фигурная инициализация названа “унифицированной'”. Из трех способов обозначения выражений инициализации только фигурные скобки могут использоваться везде.
Новая возможность фигурной инициализации заключается в том, что она запрещает неявные
double x, y, z;
…
int sum1{ x + y + z }; // Ошибка! Сумма double может
// не выражаться с помощью int
Инициализация с использованием круглых скобок и знака равенства не выполняет проверку сужающего преобразования, поскольку это может привести к неработоспособности большого количества старого кода:
int su.2(x+y+z) ; // OK (значение выражения усекается до int)
int sum3 = x+y+z; //
Обращает на себя внимание еще одна особенность фигурной инициализации — она не подвержена
Widget w1(10); // Вызов конструктора Widget с аргументом 10
Но если вы пытаетесь вызвать конструктор Widget
без аргументов с помощью аналогичного синтаксиса, то фактически объявляете функцию вместо объекта:
Widget w2(); // Синтаксический анализ рассматривает это как
// объявление функции w2, возвращающей Widget!
Функции не могут быть объявлены с использованием фигурных скобок для списка параметров, так что конструирование объекта по умолчанию с применением фигурных скобок такой проблемы не вызовет:
Widget w3{}; // Вызов конструктора Widget без аргументов
Таким образом, в пользу фигурной инициализации имеется много “за”. Это синтаксис, который может использоваться в самых разнообразных контекстах, предотвращающий неявные сужающие преобразования и не подверженный неприятностям с синтаксическим анализом С++. Тройное “за”! Так почему бы не озаглавить раздел просто “Используйте синтаксис фигурной инициализации”?