如何在c ++中专门化函数模板?
#include <iostream>
template <int X = 0> //Wrong attempt, does not compile.
int func(int y)
{
return X + y;
}
template<int X>
int func(int y)
{
return X + func<X-1>(y);
}
int main()
{
std::cout << func<1>(2);
return 0;
}
我希望这个程序的结果是:1 + 0 + y = 3.
对于y = 2,它将是:2 + 1 + 0 + y。
我知道有更好的方法来进行这种计算,我试图理解这种语言的这一方面。
答案 0 :(得分:5)
通过委派
重载该功能template <int X>
class Int
{
};
template <int X>
int funcSwitch(int y, Int<X>)
{
return X + funcSwitch(y, Int<X-1>());
}
int funcSwitch(int y, Int<0>)
{
return y;
}
template<int X>
int func(int y)
{
return funcSwitch(y, Int<X>());
}
int main()
{
std::cout << func<1>(2);
return 0;
}
您需要注意不要在Int
之外的另一个名称空间中定义funcSwitch
,因为第一个funcSwitch
中的调用将找不到第二个funcSwitch
的情况它被实例化(这是因为一个名为ADL的规则)。为了不考虑这一点,您还可以编写一个类模板来委托
template<int X>
struct FuncImpl {
int operator()(int y) const {
return X + FuncImpl<X-1>()(y);
}
};
template<>
struct FuncImpl<0> {
int operator()(int y) const {
return y;
}
};
template<int X>
int func(int y)
{
return FuncImpl<X>()(y);
}
int main()
{
std::cout << func<1>(2);
return 0;
}
一般来说,我更喜欢没有类的技术,因为如果*this
是成员函数,它允许成员函数仍然访问func
及其私有成员。
要完成,功能还有“明确的专业化”,但由于其限制和缺陷,我不推荐它。在这种情况下,它会工作,并将
template<int X>
int func(int y)
{
return X + func<X-1>(y);
}
template <>
int func<0>(int y)
{
return y;
}
int main()
{
std::cout << func<1>(2);
return 0;
}
答案 1 :(得分:0)
Johannes Schaub - litb的答案几乎涵盖了重载的所有内容。
但是你也可以记住,在某些情况下,某些编译时计算(特别是涉及整数类型的标量)可能由constexpr
函数执行,这比重载更简单。在您的具体示例中,这适用:
constexpr int f(int x) { return x ? x + f(x-1) : 0; }
template<int x>
int func(int y) { return f(x) + y; }
将x
的效果与y
的效果分开(递归仅指x
)。
答案 2 :(得分:0)
在这种情况下,不需要模板专业化。您只需使用a sum of an arithmetic progression的公式编写以下代码:0 + 1 + 2 + ... + x = x * (x + 1) / 2
。
template <int x>
int func(int y)
{
return y + x * (x + 1) / 2;
}