说我有以下代码
#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>
是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);
}