[MPL] Applying a boost::mpl::list to the template parameter of a type.

Hello, I have a class that requires a boost::variant containing shared pointers to various types as follows: template <typename ToySharedPtrVariant, typename ColorSharedPtrVariant> class ToyPicker { typedef std::pair< ToySharedPtrVariant, ColorSharedPtrVariant > toyAndColorPair; typedef std::map< std::string, std::vector< toyAndColoPair > > stringToToyColorPairMap; // ... methods that use the defined types... } This class currently requires template parameters of the following form to compile: ToyPicker< boost::variant< boost::shared_ptr<ToyModel> >, boost::variant< boost::shared_ptr<BlueToy>, boost::shared_ptr<RedToy>, boost::shared_ptr<GreenToy> > > toyPicker; How do I use an mpl list so that I can allow the following much simpler definition for users, then convert it into the one above inside my class? ToyPicker< boost::mpl::list< ToyModel >, boost::mpl::list< BlueToy, RedToy, GreenToy > > toyPicker; I really appreciate all of the user help you all give, and hope that as I become more experienced I may be able to contribute myself. Cheers! Andrew Hundt

I have a class that requires a boost::variant containing shared pointers to various types as follows: template <typename ToySharedPtrVariant, typename ColorSharedPtrVariant> class ToyPicker { typedef std::pair< ToySharedPtrVariant, ColorSharedPtrVariant > toyAndColorPair; typedef std::map< std::string, std::vector< toyAndColoPair > > stringToToyColorPairMap; // ... methods that use the defined types... } This class currently requires template parameters of the following form to compile: ToyPicker< boost::variant< boost::shared_ptr<ToyModel> >, boost::variant< boost::shared_ptr<BlueToy>, boost::shared_ptr<RedToy>, boost::shared_ptr<GreenToy> > > toyPicker; How do I use an mpl list so that I can allow the following much simpler definition for users, then convert it into the one above inside my class? ToyPicker< boost::mpl::list< ToyModel >, boost::mpl::list< BlueToy, RedToy, GreenToy > > toyPicker;
If you got you right, you map a Model to a list of Colors, right? I'm not a TMP expert, but I'd propose something like this: #include <boost/mpl/map.hpp> #include <boost/mpl/list.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/variant.hpp> #include <boost/shared_ptr.hpp> using namespace boost::mpl; using boost::shared_ptr; using boost::variant; using boost::make_variant_over; // a metafunction that will map for us maps list<a, b,...> --> list<shared_ptr<a>, shared_ptr<b>, ...> template<class Seq, template<class> class Wrapper> struct add_wrapper : transform<Seq, Wrapper<_> >{}; // now your picker class get template args of the form pair<model, list<color1, color2,...> > template<typename ModelColors> struct picker { // wrapping the model with shared_ptr and variant manually typedef variant<shared_ptr<typename ModelColors::first> > wrapped_model; // applying our metafunction to the sequence of colors, then applying make_variant_over typedef typename make_variant_over<typename add_wrapper<typename ModelColors::second, shared_ptr>::type>::type wrapped_colors; wrapped_colors colors_; wrapped_model model_; }; struct Model1; struct Color1; struct Color2; struct Color3; int main(int argc, char* argv[]) { picker<pair<Model1, list<Color1, Color2> > > p; return 0; }
participants (2)
-
Andrew Hundt
-
Igor R