問題描述
我有以下情況:假設我有一堆類型(函子),我想在編譯期間注冊/編譯它們,最好是像 boost::mpl::vector 這樣的東西.你知道有什么技巧可以做得很好嗎?
I have the following situation: suppose I have a bunch of types (functors) which I want to register/compile in during compilation, preferably into something like boost::mpl::vector. Do you know any trick to do so nicely?
我的愿望是擁有實現函子類型和注冊文件的 hpp 文件,其中宏將類型引入編譯.
My desire is to have hpp file which implements functor type and registration file, where a macro brings in type into compilation.
例如
// registered.hpp
REGISTER("functor1.hpp") // implementation
REGISTER("functor2.hpp")
...
boost::mpl::vector<...> types; // full registration vector
希望這是有道理的.謝謝
Hopefully it makes sense. Thank you
推薦答案
有一種方法可以一個一個地注冊類型,然后以 mpl::vector 或類似的形式檢索所有類型.我在 boost 郵件列表上學到了這個技巧(也許是從 Dave Abrahams 那里學到的,雖然我記不清了).
There is a way to register types one by one and then retrieve all of them in the form of mpl::vector or similar. I've learned this trick on the boost mailing lists (perhaps from Dave Abrahams, although I can't recall for sure).
我從 https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.pdf.
我不會在代碼中使用 MPL 使其自包含.
I won't use MPL in the code to make it self contained.
// 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, "")
使用示例:
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, "");
這篇關于C++ 編譯時類型注冊技巧的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!