Có một cách để đăng ký từng loại một và sau đó truy xuất tất cả chúng theo dạng mpl :: vector hoặc tương tự. Tôi đã học được điều này lừa trên danh sách gửi thư tăng (có lẽ từ Dave Abrahams, mặc dù tôi không thể nhớ lại chắc chắn).
Chỉnh sửa: Tôi đã học nó từ trang trình bày 28 trên https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.pdf.
Tôi sẽ không sử dụng MPL trong mã để tự đặt nội dung đó.
// The maximum number of types that can be registered with the same tag.
enum { kMaxRegisteredTypes = 10 };
template <int N>
struct Rank : Rank<N - 1> {};
template <>
struct Rank<0> {};
// Poor man's MPL vector.
template <class... Ts>
struct TypeList {
static const int size = sizeof...(Ts);
};
template <class List, class T>
struct Append;
template <class... Ts, class T>
struct Append<TypeList<Ts...>, T> {
typedef TypeList<Ts..., T> type;
};
template <class Tag>
TypeList<> GetTypes(Tag*, Rank<0>) { return {}; }
// Evaluates to TypeList of all types previously registered with
// REGISTER_TYPE macro with the same tag.
#define GET_REGISTERED_TYPES(Tag) \
decltype(GetTypes(static_cast<Tag*>(nullptr), Rank<kMaxRegisteredTypes>()))
// Appends Type to GET_REGISTERED_TYPES(Tag).
#define REGISTER_TYPE(Tag, Type) \
inline Append<GET_REGISTERED_TYPES(Tag), Type>::type \
GetTypes(Tag*, Rank<GET_REGISTERED_TYPES(Tag)::size + 1>) { \
return {}; \
} \
static_assert(true, "")
dụ Cách sử dụng:
struct IntegralTypes;
struct FloatingPointTypes;
// Initially both type lists are empty.
static_assert(std::is_same<GET_REGISTERED_TYPES(IntegralTypes), TypeList<>>::value, "");
static_assert(std::is_same<GET_REGISTERED_TYPES(FloatingPointTypes), TypeList<>>::value, "");
// Add something to both lists.
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, "");
// Add more types.
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, "");
Nguồn
2014-02-07 11:03:53
Bạn có liên kết đến chuỗi danh sách gửi thư không? – Xeo
Thật không may tôi không thể tìm thấy các chủ đề ban đầu mà từ đó tôi đã học được các trick. –