说我有以下代码

#include <iostream>

template<int N>
int calcFac() {

    return N*calcFac<N-1>();
}

template<>
int calcFac<1> () {

    return 1;
}

template<>
int calcFac<0> () {

    return 1;
}

int main() {

    int f4 = calcFac<4>();
    int f5 = calcFac<5>();
    int f1 = calcFac<1>();
    int f0 = calcFac<0>();

    std::cout <<"4! = "<<f4<<std::endl;
    std::cout <<"5! = "<<f5<<std::endl;
    std::cout <<"1! = "<<f1<<std::endl;
    std::cout <<"0! = "<<f0<<std::endl;

    return 0;
}

是否有可能(即STL提供一种构造)将两种特殊情况calcFac<0>calcFac<1>集中在一起,以便我在两种情况下都只需要一个函数?

即:calcFac</*if this parameter is 0 or 1 use that template function*/>

最佳答案

编辑:
我的原始设计有缺陷(无法与calcFac<0>()一起正常使用)。我改用@xaxxon的设计。保存我的原始设计需要声明三个功能,但确实会将这两个特殊情况结​​合在一起。您可以在此答案的最后找到它。

通过使用SFINAE和std::enable_if_t

#include <type_traits>
template <int N>
std::enable_if_t<N <= 1, int> calcFac() {
  return 1;
}

template<int N>
std::enable_if_t<!(N <= 1), int> calcFac() {
  return N*calcFac<N-1>();
}

这是如何运作的:

如果std::enable_if_t<exp, Type>Typeexp等效于true,否则未声明。通过这种方式在返回类型中使用std::enable_if_t,当expfalse时,将导致SFINAE错误,因此该函数不在候选列表之内。
#include <type_traits>
template <int N>
std::enable_if_t<N<=1, int> calcFacImpl(int) {
  return 1;
}

template <int N>
int calcFacImpl(...) {
  return N*calcFacImpl<N-1>(0);
}

template <int N>
int calcFac() {
  return calcFacImpl<N>(0);
}

10-04 15:08