18

我正在玩模板专业化,但我发现了一个我似乎无法解决的问题;这是我的代码:

template<int length, typename T>
void test(T* array)
{
    ...
    test<length-1>(array);
}

template<typename T>
void test<0>(T* array)
{
    return;
}

所以我想要做的是传递模板中要处理的内容的长度。

问题是,这个编译,永远输出:

a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template
a.cpp: In function 'void test(T*) [with int length= -0x000000081, T = int]':
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x000000080, T = int]'
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x00000007f, T = int]'
a.cpp:77:9:   [ skipping 151 instantiation contexts ]
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= 28, T = int]'
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= 29, T = int]'
...
a.cpp: In function 'void test(T*) [with int length= -0x000000082, T = int]':
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x000000081, T = int]'
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x000000080, T = int]'

最后两行,与第一行几乎相同。

在我看来,它没有抓住专业化,因此:

a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template

我对么?

如果我是正确的,我猜这是函数模板不允许部分模板专业化的问题,那么解决方案是什么,制作一个结构,并在上面使用专业化?

4

4 回答 4

22

不允许对函数模板进行部分特化。Herb Sutter 在他的文章“为什么不专门化函数模板?”中解释了原因。.

要解决此限制,您需要改用类模板。然后,您可以编写一个使用该类模板的常规函数​​模板。

您遇到的特定错误是因为您忘记了专业化中的第二个参数。如果你这样做:

template<int length, typename T>
void test(T* array)
{
    //...
    test<length-1,T>(array);
}


template<typename T>
void test<0,T>(T* array)
{
    return;
}

GCC 抱怨以下内容:

错误:不允许函数模板部分特化“test<0,T>”

于 2011-07-08T10:47:59.887 回答
8

函数不能部分特化。要解决此问题,请让您的模板函数调用类中的函数:

template<int length, typename T>
struct helper
{
    static void go(T* array)
    {
        ...
        helper<length-1, T>::go(array);
    }
};

template<typename T>
struct helper<0, T>
{
    static void go(T* array)
    {
        ...
    }
};

template<int length, typename T>
void test(T* array)
{
    ...
    helper<length, T>::go(array);
}
于 2011-07-08T10:49:58.560 回答
3

不允许对函数模板进行部分特化。

要解决这个问题,您可以创建test类模板的静态成员,并部分专门化该类。

于 2011-07-08T10:49:58.020 回答
2

您可以使用辅助类解决方法。出于说明目的:

template<typename T, typename U> struct helper_t {
    static int foo () { return 0; }
};

template<typename T> struct helper_t<T,T> {
    static int foo () { return 1; }
};

template <typename T, typename U>
int frob () {
    return helper_t<T,U>::foo();
}
于 2011-07-08T10:50:59.380 回答