在C ++中,我试图为一个模板化的对象专门化一个模板化函数。
这是一个基本的例子: test.h:
template <class T>
class myC {
T x;
};
template <class U>
void f(U y) {
}
template <>
template <class T>
void f<myC<T> >(myC<T> y) {
}
TEST.CPP
#include "test.h"
int main() {
myC<double> m;
f(m);
}
GCC 4.6.1给出了以下错误消息:
In file included from test.cpp:1:0:
test.h:13:25: error: too many template parameter lists in declaration of ‘void f(myC<T>)’
test.h:13:6: error: template-id ‘f<myC<T> >’ for ‘void f(myC<T>)’ does not match any template declaration
test.h:13:25: note: saw 2 ‘template<>’, need 1 for specializing a member function template
这一切都可能吗?或者还有另一种方法来实现同一目标吗?
答案 0 :(得分:4)
template <>
template <class T>
void f<myC<T> >(myC<T> y) {
}
你在这里做的事情被称为部分专业化,在功能模板的情况下是不允许的。
功能模板要么完全专用,要么根本不专门。语言规范不允许对函数模板进行部分特化。
所以你可以重载函数模板:
template <class T>
void f(myC<T> y) //note that it is overload, not specialization
{
}
是允许的,甚至比模板的完全专业化更受欢迎。
阅读Herb Sutter的这些文章:
答案 1 :(得分:2)
你不能专门化模板功能;只有模板类可以是专用的。编辑:Nawaz的答案是正确的:它是部分特化,不允许模板功能,仅适用于类。完全专业化是可能的:
template <class U> void f(U y) {}
template<> void f<double>(double y) {} // specialization for double
请注意,如果可以从上下文推导出模板参数,则无需显式指定:
template<> void f<>(int y) {} // specialization for int
在您的情况下,由于函数参数是模板类,因此无法进行完全特化。但是,模板函数与任何函数一样可以重载。在你的情况下,它将是这样的:
template <class T>
class myC {
T x;
};
template <class U>
void f(U y) {
}
template <class T>
void f(myC<T> y) {
}
int main() {
myC<double> m;
f(m);
return 0;
}
答案 2 :(得分:0)
据我所知,你不能专门化模板函数,只能模板化类(或结构)。
但这不是一个限制:只需使用静态公共成员函数声明一个结构,并将模板参数固定到结构中:
template <class T>
class myC {
T x;
};
template <class U>
struct Foo
{
static void f(U y) {
}
};
template <>
template <class T>
struct Foo<myC<T> >
{
static void f(myC<T> y) {
}
};
缺点是类模板不能自动解决模板参数。但是这可以通过功能模板轻松解决,类似于原始模板:
template <class U>
void f(U y) {
return Foo<U>::f(y);
}