8

我有表格的功能

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>(); 
4

1 回答 1

9

您不能部分特化函数模板,但可以部分特化类模板。

这为以下技巧留下了空间,其中实际工作由主函数模板和专用函数模板的静态成员函数完成,您的原始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>();
}

这是一个活生生的例子

编辑:

如果您的函数模板是成员函数,事情会稍微复杂一些,但是上面概述的将函数模板部分特化转换为类模板部分特化的解决方案仍然是可行的。

这就是您根据评论中提供的示例进行操作的方式。

首先,前向声明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>();
}

这一切都放在了这个活生生的例子中。

于 2013-05-31T21:19:35.687 回答