我正在玩模板专业化,我发现了一个似乎无法解决的问题;这是我的代码:
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
我说错了吗?
如果我是正确的,我猜测这是一个问题,即功能模板不允许部分模板专业化,那么解决方案是什么,制作一个结构,并使用专门化呢?
答案 0 :(得分:17)
不允许对功能模板进行部分特化。 Herb Sutter在他的文章"Why Not Specialize Function Templates?"中解释了原因。
要解决此限制,您需要使用类模板。然后,您可以编写使用该类模板的常规函数模板。
您遇到的具体错误是因为您忘记了专业化中的第二个参数。如果你改为:
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 complains包含以下内容:
错误:函数模板部分特化'test&lt; 0,T&gt;'不允许
答案 1 :(得分:7)
功能不能部分专业化。要解决此问题,请让模板函数在类中调用函数:
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);
}
答案 2 :(得分:3)
功能模板的部分专业化is not allowed。
要解决此问题,您可以使test
成为类模板的静态成员,并部分地对该类进行专门化。
答案 3 :(得分: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();
}