Простой C ++ 11 факториал constexpr с троичным превышает максимальную глубину шаблона

Если я напишу факториальную функцию во время компиляции, используя специализацию, следующего кода может быть достаточно, и он будет правильно предоставлять 120 в результате fact1<5>():

template <size_t N>
constexpr size_t fact1() { return N*fact1<N-1>(); }

template <>
constexpr size_t fact1<0>() { return 1; }

Однако с одним телом функции и троичным оператором, как в следующем коде, G ++ 4.7 и Clang ++ 3.2 оба превышают максимальную глубину создания шаблона. Похоже, что 1 никогда не возвращается из fact2, Почему это определение fact2<5>() не возвращает 120?

template <size_t N>
constexpr size_t fact2() { return N==0 ? 1 : N*fact2<N-1>(); }

4

Решение

Проблема в том, что несмотря ни на что, fact2<N-1> будут всегда быть созданным (даже неисполненные пути должны быть скомпилированы, см. Эффективный C ++, я думаю, что пункт 47 или 48). Вам нужно каким-то образом сделать так, чтобы он только создавал следующую функцию, если вы не в конце. Одним из способов было бы просто сказать «виндовые шаблоны» и пойти обычным constexpr так, как @NicolBolas говорит в своем комментарии.

Другой будет использовать один из методов, используемых в этот похожий вопрос.

7

Другие решения

Других решений пока нет …