Функция уже помечена constexpr. Чтобы гарантировать раннее вычисление, используйте результат в constexpr-переменной или static_assert; один лишь вызов constexpr-функции такой гарантии не даёт.
Компиляционное вычисление факториала через constexpr
Функция уже помечена constexpr. Чтобы гарантировать раннее вычисление, используйте результат в constexpr-переменной или static_assert; один лишь вызов constexpr-функции такой гарантии не даёт.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Дана рекурсивная функция, считающая факториал числа. Требуется переписать её так, чтобы результат получался уже во время компиляции, используя возможности constexpr. При этом можно изменить имена параметров и переменных, но саму логику оставить той же.
constexpr unsigned long long fact(unsigned int value) {
return (value == 0) ? 1 : fact(value - 1) * value;
}
Ответ
Функция уже помечена constexpr. Чтобы гарантировать раннее вычисление, используйте результат в constexpr-переменной или static_assert; один лишь вызов constexpr-функции такой гарантии не даёт.
constexpr unsigned long long result = fact(5);
static_assert(result == 120);
При обычном вызове с runtime-аргументом функция остаётся допустимой и вычисляется во время выполнения, если компилятор не может её свернуть. Для безусловного требования константного вызова есть consteval в C++20.
На реализации с 64-битным unsigned long long точный результат помещается до 20! включительно. Дальше без проверки получится беззнаковое переполнение по модулю, а не математический факториал.