Reputation: 33
In C++, I am trying to specialize a templated function for a object that is templated itself.
Here is a basic example: 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 gives me the following error message:
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
Is this at all possible? Or is there another way to accomplish the same goal?
Upvotes: 2
Views: 3324
Reputation: 12784
You cannot specialize a template function; only template classes can be specialized. Edit: Nawaz's answer is correct: it's partial specialization that is not allowed for template functions, only for classes. A full specialization is possible:
template <class U> void f(U y) {}
template<> void f<double>(double y) {} // specialization for double
Note that the template argument need not be explicitly specified if it can be deduced from the context:
template<> void f<>(int y) {} // specialization for int
In your case, full specialization is not possible because the function argument is a template class. However, a template function, like any function, can be overloaded. In your case, it will be like this:
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;
}
Upvotes: 2
Reputation: 361412
template <>
template <class T>
void f<myC<T> >(myC<T> y) {
}
What you're atttempting to be doing here is called partial specialization which is not allowed in case of function template.
A function template is either fully specialized, or not specialized at all. No partial specialization of function template is allowed by the language specification.
So you can overload the function template as:
template <class T>
void f(myC<T> y) //note that it is overload, not specialization
{
}
which is allowed, and preferred over even fully specialization of template.
Read these articles by Herb Sutter:
Upvotes: 4
Reputation: 98358
As far as I can tell, you cannot specialize template functions, only template classes (or structs).
But that is hardly a limitation: just declare a struct with static public member functions and mave the template parameters to the struct:
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) {
}
};
The drawback is that class templates do not solve the template parameters automatically. But that can be easlily solved with a function template, similar to the original one:
template <class U>
void f(U y) {
return Foo<U>::f(y);
}
Upvotes: 0