整合模板专业化

时间:2017-02-16 23:46:28

标签: c++ c++11 templates

说我有以下代码

#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*/>

2 个答案:

答案 0 :(得分:3)

编辑: 我的原始设计存在缺陷(与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>Type,则

exp相当于true,否则为未声明。通过这种方式在返回类型中使用std::enable_if_texpfalse时会导致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);
}

答案 1 :(得分:0)

在即将标准化的C ++ 1z中,您可以使用if constexpr

template<int N>
auto calcFac() {
    if constexpr (N > 1)  {
        return N * calcFac<N-1>();
    }
    return 1;
}

Live Example