问题
I need to make a specialization of my function with template class and have problem with "illegal use of explicit template arguments".
template <typename T>
class MyClass { /* ... */ }; // it can be any template class, eg std::vector
template <typename T>
void foo() { /* ... */ } // my template function which need a specialization
template<>
void foo<int>() /* sth special for integers - it works */ }
template<template T>
void foo<MyClass<T> >() /* sth special for template class with any parameter - it doesnt work :( */ }
Of course i can type a few specialization for all MyClass'es which i need to, but maybe it can be replaced with one?
回答1:
Template specialization of function is not as flexible as specialization of struct
: only full specialization is allowed. If you want to do partial specialization you need to wrap your foo
function inside a struct
:
template <typename T> class MyClass { };
template <typename T> struct Foo;
template <typename T> struct Foo { void foo() {}};
template<> struct Foo<int> { void foo() { } };
template<typename T> struct Foo< MyClass<T> > { void foo() {} };
And then instead of calling
foo<MyClass<...>>()
you call
Foo< MyClass<...> >::foo()
回答2:
You cannot partially speciallise a template function. There are discussions about removing that restriction though.
The advocated workarounds are:
- Use a class template from the template function.
- Wrap your function in a template class.
template <typename T>
struct foo_impl {
};
template <typename T>
void foo() {
foo_impl<T>();
}
// And now specialize foo_impl as you want:
template<>
struct foo_impl<int> {
foo_impl(){/* sth special for integers - it works */}
};
template<typename T>
struct foo_impl<myclass<T>> {
foo_impl() {/* ... */}
};
If you wanted a return-value, you should use a member-function - probably operator()
- instead of the ctor.
回答3:
This is a lot of extra typing, but how about:
template <typename T>
class MyClass { /* ... */ }; // it can be any template class, eg std::vector
template<typename T>
struct FooWrapper
{
static void foo()
{
// default implementation
}
};
template<typename T>
struct FooWrapper<MyClass<T>>
{
static void foo()
{
// MyClass<T> implementation
}
};
template<typename T>
void foo()
{
FooWrapper<T>::foo();
}
回答4:
A possible solution could be using a base class
template<typename T> class MyClass;
class base {
private:
template<typename T> friend class MyClass;
base(); // Can't build a base object directly
};
template <typename T>
class MyClass : public base {
public:
}; // it can be any template class, eg std::vector
template <typename T>
void foo() {
} // my template function which need a specialization
template<>
void foo<int>() { /* sth special for integers - it works */ }
template<>
void foo<base>() { /* sth special for template class with any parameter - it doesnt work :( */ }
The above might also work in case you want a template parameter to your function. If you can wrap your function up I'd go with hivert's solution.
来源:https://stackoverflow.com/questions/23550281/function-specialized-with-template