
AMDG Robert Dailey wrote:
Would you mind going over what exactly this is doing? I'm having a hard time wrapping my head around it. The documentation isn't helping much either, as I've never used these before and the descriptions are very confusing.
I also didn't see a version of mpl::transform that only took 1 template argument. Is this correct?
You're right. I was in too much of a hurry before. Here's something that actually compiles. #include <boost/mpl/vector.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/inherit_linearly.hpp> #include <boost/mpl/inherit.hpp> #include <boost/signal.hpp> #include <boost/variant.hpp> namespace mpl = boost::mpl; // bring _ into scope. using namespace mpl::placeholders; struct WalkPacket {}; struct ChatPacket {}; struct QuestPacket {}; // a metafunction to create a signal type that // takes T as is argument by const reference. template<class T> struct make_signal { typedef boost::signal<void(T const&)> type; }; // a type list of all the possible packet types. typedef mpl::vector<WalkPacket, ChatPacket, QuestPacket> packet_types; // take the list of packet types and transform it // to get the signal types. The result will be // equivalent to // mpl::vector<signal<void(WalkPacket const&)>, signal<void(ChatPacket const&)>, signal<void(QuestPacket const&)> > // // make_signal<_> is an mpl lambda expression. _ // is a placeholder which in this context means // to substitute the first argument to the // metafunction. In other words mpl::apply<make_signal<_>, T> // will replace _ with T and then return the nested ::type // typename make_signal<T>::type. typedef mpl::transform<packet_types, make_signal<_> >::type signals; // A type that inherits from all of the signal types. // // The mpl::inherit<_, _> is similar to make_signal<_> above, // except that the first _ refers to the first argument and // and the second _ refers to the second argument. // mpl::inherit_linearly starts with an initial base class // which defaults to mpl::empty_base, takes the // first type in signals, and applies mpl::inherit to // the two bases. inherit<empty_base, WalkPacket>. // Then, it continues with the second element of signals // to get inherit<inherit<empty_base, WalkPacket>, ChatPacket> // And so on. // inherit just inherits from both it's arguments. // // This could really be replaced by a fusion::set. typedef mpl::inherit_linearly<signals, mpl::inherit<_, _> >::type signal_holder; struct signal_visitor : boost::static_visitor<> { explicit signal_visitor(signal_holder& holder) : holder_(holder) {} signal_holder& holder_; template<class T> void operator()(T const& t) const { // up-cast to correct type of signal. return(static_cast<typename make_signal<T>::type&>(holder_)(t)); } }; typedef boost::make_variant_over<packet_types>::type packet; int main() { packet p = WalkPacket(); signal_holder signals; boost::apply_visitor(signal_visitor(signals), p); } In Christ, Steven Watanabe