Читать «Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14» онлайн - страница 44

Скотт Мейерс

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

Второй урок заключается в том, что в качестве клиента класса вы должны тщательно выбирать между круглыми и фигурными скобками при создании объектов. Большинство разработчиков в конечном итоге выбирают один вид скобок как применяемый по умолчанию, а другой — только при необходимости. Применение по умолчанию фигурных скобок привлекает их непревзойденным диапазоном применимости, запретом применения сужающих преобразований и их иммунитетом к особенностям синтаксического анализа. Такие люди понимают, что в некоторых случаях (например, при создании вектора std::vector с заданными размером и начальным значением элемента) необходимо использовать круглые скобки. С другой стороны, немало программистов используют в качестве выбора по умолчанию круглые скобки. Они привлекательны своей согласованностью с синтаксическими традициями С++98, тем, что позволяют избегать проблем с выводом auto как std::initializer_list, и уверенностью, что вызовы при создании объектов не приведут к случайным вызовам конструкторов с std::initializer_list. Эти программисты признают, что иногда следует использовать именно фигурные скобки (например, при создании контейнера с определенными значениями). Нет определенного превалирующего мнения о том, какой подход лучше, поэтому могу посоветовать только выбрать один из них и постоянно ему следовать.

Если вы автор шаблона, противостояние в применении круглых и фигурных скобок может быть особенно неприятным, потому что в общем случае невозможно сказать, какие скобки должны использоваться. Предположим, например, что вы хотите создать объект произвольного типа с произвольным количеством аргументов. Использование шаблонов с переменным количеством параметров позволяет сделать это концептуально достаточно просто: