Приведённый шаблон уже выполняет задачу: get — constexpr-метод экземпляра, а специализация Fac<0> завершает рекурсию. static_assert требует вычислить Fac<5>().get() при компиляции.
Компиляторное вычисление факториала в шаблоне без static‑контекста
Приведённый шаблон уже выполняет задачу: get — constexpr-метод экземпляра, а специализация Fac<0> завершает рекурсию. static_assert требует вычислить Fac<5>().get() при компиляции.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Создан шаблонный метакласс Fac<N>, который позволяет вычислить факториал уже на этапе компиляции. Задача состоит в том, чтобы избавиться от использования static constexpr и реализовать расчёт через constexpr‑метод экземпляра класса.
template <unsigned N>
struct Fac {
constexpr int get() const {
return N * Fac<N - 1>().get();
}
};
template <>
struct Fac<0> {
constexpr int get() const {
return 1;
}
};
static_assert(Fac<5>().get() == 120);
Ответ
Приведённый шаблон уже выполняет задачу: get — constexpr-метод экземпляра, а специализация Fac<0> завершает рекурсию. static_assert требует вычислить Fac<5>().get() при компиляции.
Можно также написать constexpr int value = Fac<5>{}.get(); и использовать value как константу. Создаваемые временные экземпляры не содержат данных; значение определяется параметром шаблона N.
Без константного контекста constexpr лишь разрешает раннее вычисление, но не требует его. Для больших N нужно учитывать предел int и глубину инстанцирования шаблонов; сам способ вычисления не защищает от выхода за диапазон.