参数值相等时的模板特化

时间:2013-05-31 21:15:28

标签: c++ templates template-specialization specialization

我有一个

形式的功能
template<int a, int b>
void f();

我想专注于a == b。伪代码看起来像:

template<int a>
void f<a, a>(){ //something}

template<int a, int b>
void f<a, b>(){ //something different}

如果没有部分模板专业化问题,这可能吗?

编辑:感谢您的快速回复。该方法实际上是在类中,更像是:

<typename a> class A{ 
    template<int b, int c> f(); 
}; 

A inst; 
inst.f<1,1>(); 
inst.f<1,2>(); 

1 个答案:

答案 0 :(得分:6)

您不能部分专门化功能模板,但可以部分专门化类模板。

这为以下技巧留下了空间,其中实际工作由主要功能模板的静态成员函数和专用函数模板完成,原始f()函数委托其负责:

#include <iostream>

namespace detail
{
    template<int A, int B>
    struct helper
    {
        static void call() { std::cout << "f<A, B>()" << std::endl; }
    };

    template<int A>
    struct helper<A, A>
    {
        static void call() { std::cout << "f<A, A>()" << std::endl; }
    };
}

template<int a, int b>
void f()
{
    detail::helper<a, b>::call();
}

这是您使用f()功能模板的方法:

int main()
{
    f<1, 2>();
    f<1, 1>();
}

这是live example

修改

如果你的函数模板是一个成员函数,事情会稍微复杂一点,但上面提到的将函数模板局部特化转化为类模板局部特化的解决方案仍然可行。

这就是基于example provided in the comments

的方法

首先,向前声明helper类模板并授予其实例化访问类模板A的私有成员的权限(附加类型参数T的角色将马上变得清晰):

namespace detail
{
    template<typename T, int A, int B>
    struct helper;
}

template <typename a>
class A
{
public:
    template<int b, int c>
    void f();
private:
    template<typename, int, int> friend struct detail::helper;
};

然后你将如前所述定义helper类模板及其特化,但是将函数参数添加到操作原始成员函数所在的类对象所需类型的call()函数中已调用f()

namespace detail
{
    template<typename T, int A, int B>
    struct helper
    {
        static void call(T* p) { std::cout << "f<A, B>()" << std::endl; }
    };

    template<typename T, int A>
    struct helper<T, A, A>
    {
        static void call(T* p) { std::cout << "f<A, A>()" << std::endl; }
    };
}

然后你可以定义成员函数f(),如下所示:

template<typename a>
template<int b, int c>
void A<a>::f()
{
    detail::helper<A<a>, b, c>::call(this);
}

并最终以这种方式使用它:

int main()
{
    A<int> inst;
    inst.f<1,1>();
    inst.f<1,2>();
}

这一切都放在这个live example中。