Reputation: 105
I have the following traits class
template<typename T> struct FeatureType;
and I'm using it like so, which works fine:
class Foo { };
template<> struct FeatureType<Foo> {
typedef int value;
};
template<typename T> class Bar { };
template<typename T> struct FeatureType<Bar<T>> {
typedef T value;
};
Is there a way to extent this implementation for generic types to those that have more than one type parameter (unlike Bar
above)? The following does not work
template<typename A, typename B> class Huh { };
template<typename A, typename B> struct FeatureType<Huh<A,B>> {
typedef A value;
};
Thanks!
Upvotes: 1
Views: 224
Reputation: 70526
Regular templates do not overload on their template parameters, but you can partially specialize them on arbitrary many template parameters. Your code should work as long as you put ;
behind every struct declaration/definition. (note it is a custom to denote nested types inside templates as type
, and values as value
):
#include <iostream>
template<typename T>
struct FeatureType;
class Foo { };
template<> struct FeatureType<Foo>
{
typedef int type;
type value;
};
template<typename T> class Bar { };
template<typename T> struct FeatureType<Bar<T>>
{
typedef T type;
type value;
};
template<typename A, typename B> class Huh {};
template<typename A, typename B>
struct FeatureType< Huh<A,B> >
{
typedef A type;
type value;
};
int main()
{
FeatureType<Foo> f0;
f0.value = 0;
FeatureType< Bar<int> > f1;
f1.value = 1;
FeatureType< Huh<int, int> > f2;
f2.value = 2;
std::cout << f0.value << f1.value << f2.value;
}
Output on LiveWorkSpace (gcc 4.7.2)
Note: even if you have multiple formal template parameters (A
, B
, or as many as you like), the actual template is partially specialized for the single class Huh<A, B>
If you actually want to have multiple versions of FeatureType
taking a different number of template parameters, you need to use variadic templates (C++11)
#include <iostream>
template<typename... Args>
struct FeatureType;
template<> struct FeatureType<int>
{
typedef int type;
type value;
};
template<typename T> struct FeatureType< T >
{
typedef T type;
type value;
};
template<typename A, typename B>
struct FeatureType< A, B >
{
typedef A type;
type value;
};
int main()
{
FeatureType< int > f0;
f0.value = 0;
FeatureType< int > f1;
f1.value = 1;
FeatureType< int, int > f2;
f2.value = 2;
std::cout << f0.value << f1.value << f2.value;
}
Output on LiveWorkSpace
Upvotes: 1
Reputation: 110658
I'm not sure exactly what you tried, but you sure can specialize with as many template arguments as you like:
template <typename A, typename B>
class foo { };
template <typename T>
struct feature_type {};
template <typename A, typename B>
struct feature_type<foo<A,B>> {
typedef A type1;
typedef A type2;
};
int main(int argc, const char* argv[])
{
typename feature_type<foo<int,char>>::type1 x;
typename feature_type<foo<int,char>>::type2 y;
return 0;
}
Upvotes: 0