Используйте `constexpr` для значений, вычисляемых во время компиляции
Причина
Лучшая производительность, более тщательная проверка на этапе компиляции, гарантированное вычисление во время компиляции, отсутствие возможности состояний гонки.
Пример
double x = f(2); // возможно вычисление во время выполнения
const double y = f(2); // возможно вычисление во время выполнения
constexpr double z = f(2); // ошибка, если f(2) не может быть вычислено во время компиляции
Примечание
См. F.4.
Контроль
- Помечать определения
constс инициализаторами из константных выражений.
T: Шаблоны и обобщённое программирование
Обобщённое программирование — это программирование с использованием типов и алгоритмов, параметризованных типами, значениями и алгоритмами. В C++ обобщённое программирование поддерживается языковым механизмом template.
Аргументы обобщённых функций характеризуются наборами требований к задействованным типам аргументов и значениям. В C++ эти требования выражаются в виде предикатов времени компиляции, называемых концептами.
Шаблоны также могут использоваться для метапрограммирования, то есть программ, которые компонуют код во время компиляции.
Центральным понятием в обобщённом программировании являются «концепты» — требования к аргументам шаблона, представленные как предикаты времени компиляции. «Концепты» были стандартизированы в C++20, хотя первоначально стали доступны, с несколько иным синтаксисом, в GCC 6.1.
Краткое описание правил использования шаблонов:
- T.1: Используйте шаблоны для повышения уровня абстракции кода
- T.2: Используйте шаблоны для выражения алгоритмов, применимых ко многим типам аргументов
- T.3: Используйте шаблоны для выражения контейнеров и диапазонов
- T.4: Используйте шаблоны для манипуляции синтаксическими деревьями
- T.5: Комбинируйте обобщённые и ОО-техники, усиливая их достоинства, но не их недостатки
Краткое описание правил использования концептов:
- T.10: Задавайте концепты для всех аргументов шаблона
- T.11: Везде, где возможно, используйте стандартные концепты
- T.12: Предпочитайте имена концептов вместо
autoдля локальных переменных - T.13: Предпочитайте сокращённую запись для простых концептов с одним типовым аргументом
- ???
Краткое описание правил определения концептов:
- T.20: Избегайте «концептов» без содержательной семантики
- T.21: Требуйте полный набор операций для концепта
- T.22: Задавайте аксиомы для концептов
- T.23: Различайте уточнённый концепт и его более общий случай, добавляя новые паттерны использования
- T.24: Используйте классы-теги или трейты для различения концептов, отличающихся только семантикой
- T.25: Избегайте взаимодополняющих ограничений
- T.26: Предпочитайте определять концепты через паттерны использования, а не через простой синтаксис
- T.30: Используйте отрицание концепта (
!C<T>) умеренно для выражения незначительных различий - T.31: Используйте дизъюнкцию концептов (
C1<T> || C2<T>) умеренно для выражения альтернатив - ???
Краткое описание правил интерфейса шаблонов:
- T.40: Используйте функциональные объекты для передачи операций алгоритмам
- T.41: Требуйте в концептах шаблона только существенные свойства
- T.42: Используйте псевдонимы шаблонов для упрощения записи и скрытия деталей реализации
- T.43: Предпочитайте
usingвместоtypedefдля определения псевдонимов - T.44: Используйте шаблоны функций для вывода аргументов шаблона класса (где применимо)
- T.46: (удалено)
- T.47: Избегайте хорошо видимых неограниченных шаблонов с распространёнными именами
- T.48: Если компилятор не поддерживает концепты, эмулируйте их через
enable_if - T.49: По возможности избегайте стирания типов
Краткое описание правил определения шаблонов:
- T.60: Минимизируйте зависимости шаблона от контекста
- T.61: Не перепараметризуйте члены (SCARY)
- T.62: Размещайте члены шаблона класса, не зависящие от параметров шаблона, в нешаблонном базовом классе
- T.64: Используйте специализацию для предоставления альтернативных реализаций шаблонов классов
- T.65: Используйте диспетчеризацию по тегам для предоставления альтернативных реализаций функций
- T.67: Используйте специализацию для предоставления альтернативных реализаций нестандартных типов
- T.68: Используйте
{}вместо()внутри шаблонов во избежание неоднозначностей - T.69: Внутри шаблона не вызывайте неквалифицированные не-члены-функции, если вы не намерены сделать их точками настройки
Краткое описание правил шаблонов и иерархий:
- T.80: Не шаблонизируйте иерархию классов без необходимости
- T.81: Не смешивайте иерархии и массивы
- T.82: Линеаризуйте иерархию, когда виртуальные функции нежелательны
- T.83: Не объявляйте шаблон функции-члена виртуальным
- T.84: Используйте нешаблонную основную реализацию для предоставления ABI-стабильного интерфейса
- T.??: ????
Краткое описание правил вариадических шаблонов:
- T.100: Используйте вариадические шаблоны, когда нужна функция с переменным числом аргументов различных типов
- T.101: ??? Как передавать аргументы вариадическому шаблону ???
- T.102: ??? Как обрабатывать аргументы вариадического шаблона ???
- T.103: Не используйте вариадические шаблоны для однородных списков аргументов
- T.??: ????
Краткое описание правил метапрограммирования:
- T.120: Используйте шаблонное метапрограммирование только когда это действительно необходимо
- T.121: Используйте шаблонное метапрограммирование главным образом для эмуляции концептов
- T.122: Используйте шаблоны (обычно псевдонимы шаблонов) для вычисления типов во время компиляции
- T.123: Используйте функции
constexprдля вычисления значений во время компиляции - T.124: Предпочитайте использовать средства TMP стандартной библиотеки
- T.125: Если нужно выйти за пределы средств TMP стандартной библиотеки, используйте существующую библиотеку
- T.??: ????
Краткое описание прочих правил шаблонов:
- T.140: Если операция может быть повторно использована, дайте ей имя
- T.141: Используйте безымянную лямбду, если простой функциональный объект нужен только в одном месте
- T.142: Используйте переменные-шаблоны для упрощения записи
- T.143: Не пишите непреднамеренно необобщённый код
- T.144: Не специализируйте шаблоны функций
- T.150: Проверяйте соответствие класса концепту с помощью
static_assert - T.??: ????
T.gp: Обобщённое программирование
Обобщённое программирование — это программирование с использованием типов и алгоритмов, параметризованных типами, значениями и алгоритмами.