有一种逐个注册类型的方法,然后以mpl::vector或类似形式检索所有类型。我在boost邮件列表上学到了这个技巧(也许是来自Dave Abrahams,但我不确定)。
编辑:我从第28页幻灯片上学到了这个技巧:https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.pdf。
我不会在代码中使用MPL使其自包含。
enum ;
template <int N>
struct Rank : Rank<N - 1> ;
template <>
struct Rank<0> ;
template <class... Ts>
struct TypeList ;
template <class List, class T>
struct Append;
template <class... Ts, class T>
struct Append<TypeList<Ts...>, T> ;
template <class Tag>
TypeList<> GetTypes(Tag*, Rank<0>) ; }
#define GET_REGISTERED_TYPES(Tag) \
decltype(GetTypes(static_cast<Tag*>(nullptr), Rank<kMaxRegisteredTypes>()))
#define REGISTER_TYPE(Tag, Type) \
inline Append<GET_REGISTERED_TYPES(Tag), Type>::type \
GetTypes(Tag*, Rank<GET_REGISTERED_TYPES(Tag)::size + 1>) ; \
} \
static_assert(true, "")
使用示例:
struct IntegralTypes;
struct FloatingPointTypes;
static_assert(std::is_same<GET_REGISTERED_TYPES(IntegralTypes), TypeList<>>::value, "");
static_assert(std::is_same<GET_REGISTERED_TYPES(FloatingPointTypes), TypeList<>>::value, "");
REGISTER_TYPE(IntegralTypes, int);
REGISTER_TYPE(FloatingPointTypes, float);
static_assert(std::is_same<GET_REGISTERED_TYPES(IntegralTypes), TypeList<int>>::value, "");
static_assert(std::is_same<GET_REGISTERED_TYPES(FloatingPointTypes), TypeList<float>>::value, "");
REGISTER_TYPE(IntegralTypes, long);
REGISTER_TYPE(FloatingPointTypes, double);
static_assert(std::is_same<GET_REGISTERED_TYPES(IntegralTypes), TypeList<int, long>>::value, "");
static_assert(std::is_same<GET_REGISTERED_TYPES(FloatingPointTypes), TypeList<float, double>>::value, "");