我有一个特征类,它包含每个类在 boost::fusion::map 中的所有信号。
例子:
template <typename T> struct EventTraits;
class SomeClass;
template <> struct EventTraits<SomeClass>
{
struct Started;
struct Finished;
typedef boost::fusion::map<
boost::fusion::pair<Started, boost::signals2::signal<void()>>,
boost::fusion::pair<Finished, boost::signals2::signal<void(int)>>
> Events;
};
因为我经常需要这种 traits 特化,所以我想要一个宏来节省我一些打字时间,就像这个想象中的例子:
CONSTRUCT_EVENTS(
SomeClass,
(Started, void())
(Finished, void(int))
)
我如何实现这样的 CONSTRUCT_EVENTS
宏?
作为起点,我查看了 BOOST_FUSION_ADAPT_STRUCT
,然后查看了 Boost Preprocessor,但我还没有使用后者,所以我希望有人能指导我。
最佳答案
这是应该起作用的东西:
#include <boost/fusion/container/map.hpp>
#include <boost/preprocessor.hpp>
#include <boost/signals2.hpp>
template <typename T> struct EventTraits;
#define DECLARE_EVENT_STRUCT(r, data, elem) struct BOOST_PP_TUPLE_ELEM(2,0,elem);
#define DECLARE_MAP_ITEM(r, data, i, elem) BOOST_PP_COMMA_IF(i) boost::fusion::pair<BOOST_PP_TUPLE_ELEM(2,0,elem), boost::signals2::signal<BOOST_PP_TUPLE_ELEM(2,1,elem)> >
#define CONSTRUCT_EVENTS_(Name, EventSeq) \
class Name; \
template <> struct EventTraits<Name> \
{ \
BOOST_PP_SEQ_FOR_EACH(DECLARE_EVENT_STRUCT, _, EventSeq) \
typedef boost::fusion::map \
< \
BOOST_PP_SEQ_FOR_EACH_I(DECLARE_MAP_ITEM, _, EventSeq) \
> Events; \
}; \
/***/
//! Stuff to transform (A,B)(C,D) into ((A,B))((C,D)) so BOOST_PP_SEQ_FOR_EACH can be used. (sequence of tuples)
#define ADD_PAREN_1(A, B) ((A, B)) ADD_PAREN_2
#define ADD_PAREN_2(A, B) ((A, B)) ADD_PAREN_1
#define ADD_PAREN_1_END
#define ADD_PAREN_2_END
#define CONSTRUCT_EVENT(Name, EventSeq) \
CONSTRUCT_EVENTS_(Name, BOOST_PP_CAT(ADD_PAREN_1 EventSeq,_END)) \
/***/
//! Check the output (I use this on visual studio)
#pragma message(BOOST_PP_STRINGIZE((CONSTRUCT_EVENT(SomeClass, (Started, void())(Finished, void(int))))))
//! Result (with formatting applied)
class SomeClass;
template <>
struct EventTraits<SomeClass>
{
struct Started;
struct Finished;
typedef boost::fusion::map
<
boost::fusion::pair<Started, boost::signals2::signal<void()> >
, boost::fusion::pair<Finished, boost::signals2::signal<void(int)> >
> Events;
};
int main()
{
return 0;
}
关于c++ - 通过自定义宏构造 boost::fusion::map(以及更多),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25238924/