说我有以下代码
#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*/>
答案 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_t
,exp
为false
时会导致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;
}