I want to specialize a class template with the following function:
template <typename T>
class Foo
{
public:
static int bar();
};
The function has no arguments and shall return a result based on the type of Foo. (In this toy example, we return the number of bytes of the type, but in the actual application we want to return some meta-data object.) The specialization works for fully specified types:
// specialization 1: works
template <>
int Foo<int>::bar() { return 4; }
// specialization 2: works
template <>
int Foo<double>::bar() { return 8; }
// specialization 3: works
typedef pair<int, int> IntPair;
template <>
int Foo<IntPair>::bar() { return 2 * Foo<int>::bar(); }
However, I would like to generalize this to types that depend on (other) template parameters themselves. Adding the following specialization gives a compile-time error (VS2005):
// specialization 4: ERROR!
template <>
template <typename U, typename V>
int Foo<std::pair<U, V> >::bar() { return Foo<U>::bar() + Foo<V>::bar(); }
I am assuming this is not legal C++, but why? And is there a way to implement this type of pattern elegantly?
Partitial specialization is valid only for classes, not functions.
Workaround:
template <typename U, typename V>
class Foo<std::pair<U, V> > {
public:
static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};
If you does not want to specialize class fully, use auxiliary struct
template<class T>
struct aux {
static int bar();
};
template <>int aux <int>::bar() { return 4; }
template <>int aux <double>::bar() { return 8; }
template <typename U, typename V>
struct aux <std::pair<U, V> > {
static int bar() { return Foo<U>::bar() + Foo<V>::bar(); }
};
template<class T>
class Foo : aux<T> {
// ...
};
It is perfectly legal in C++, it's Partial Template Specialization.
Remove the template <>
and if it doesn't already exists add the explicit class template specialization and it should compile on VS2005 (but not in VC6)
// explicit class template specialization
template <typename U, typename V>
class Foo<std::pair<U, V> >
{
public:
static int bar();
};
template <typename U, typename V>
int Foo<std::pair<U, V> >::bar() { return Foo<U>::bar() + Foo<V>::bar(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With