I want to make a traits class apply to a type as well as its descedants. Is this possible?
template <typename E>
struct Garble {
};
template <typename T>
struct wooble_traits;
template <typename E>
struct wooble_traits<Garble<E>> {
typedef E elem_type;
};
struct IntGarble : public Garble<int> {
};
typedef typename wooble_traits<IntGarble>::elem_type IGType;
//Error, wooble_traits<IntGarble> has no definition.
Is there some way to instead say (borrowing and abusing Java notation):
template <typename E>
struct wooble_traits<? extends Garble<E>> {
typedef E elem_type
};
typedef typename wooble_traits<IntGarble>::elem_type IGType;
//Fine, IGType is an alias for int
Note:
Attempting to adapt Dyp's solution to my example doesn't work since Garble takes a type parameter. There doesn't seem to be anywhere to infer that parameter.
#include <boost/type_traits/is_base_of.hpp>
template <typename T, typename C = void>
struct wooble_traits;
template <typename T, typename E>
struct wooble_traits<T, typename boost::is_base_of<Garble<E>, T>::type> {
typedef E elem_type;
};
in gcc-4.6 this produces:
g++ -I/usr/include/boost/utility -I/usr/include/boost/type_traits -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
../main.cpp:15:8: error: template parameters not used in partial specialization:
../main.cpp:15:8: error: ‘E’
make: *** [main.o] Error 1
which is understandable since there's no way for GCC to know the value of E.