专门研究功能模板

时间:2014-03-22 16:44:42

标签: c++ templates template-specialization

如何在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。

我知道有更好的方法来进行这种计算,我试图理解这种语言的这一方面。

3 个答案:

答案 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;
}