Если функция может потребоваться для вычисления во время компиляции, объявите её `constexpr`
Причина
constexpr необходим, чтобы указать компилятору разрешить вычисление во время компиляции.
Пример
Печально знаменитый факториал:
constexpr int fac(int n)
{
constexpr int max_exp = 17; // constexpr позволяет использовать max_exp в Expects
Expects(0 <= n && n < max_exp); // предотвращает глупость и переполнение
int x = 1;
for (int i = 2; i <= n; ++i) x *= i;
return x;
}
Это C++14. Для C++11 используйте рекурсивную формулировку fac().
Примечание
constexpr не гарантирует вычисление во время компиляции; он лишь гарантирует, что функция может быть вычислена во время компиляции для аргументов константных выражений, если программист этого требует или компилятор решает оптимизировать.
constexpr int min(int x, int y) { return x < y ? x : y; }
void test(int v)
{
int m1 = min(-1, 2); // вероятно, вычисление во время компиляции
constexpr int m2 = min(-1, 2); // вычисление во время компиляции
int m3 = min(-1, v); // вычисление во время выполнения
constexpr int m4 = min(-1, v); // ошибка: нельзя вычислить во время компиляции
}
Примечание
Не пытайтесь сделать все функции constexpr. Большинство вычислений лучше всего выполнять во время выполнения.
Примечание
Любой API, который в конечном счёте может зависеть от высокоуровневой конфигурации во время выполнения или бизнес-логики, не должен быть объявлен constexpr. Такая настройка не может быть вычислена компилятором, и любые зависящие от этого API функции constexpr придётся рефакторировать или лишить constexpr.
Контроль
Невозможно и не нужно. Компилятор выдаёт ошибку, если не-constexpr функция вызывается там, где требуется константа.