
Well, my mpl adventure continues. I'm trying to place pair members of a sequence with their keys: #include <boost/type_traits.hpp> #include <boost/mpl/pair.hpp> #include <boost/mpl/key_type.hpp> #include <boost/mpl/map.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/replace_if.hpp> #include <boost/mpl/int.hpp> #include <iostream> #include <typeinfo> using namespace boost; using namespace boost::mpl; struct pair_base {}; template<typename Key, typename Value> struct pair_type : public pair<Key, Value>, private pair_base {}; template<typename Sequence> struct replaceit { typedef typename replace_if< Sequence, is_base_and_derived<pair_base, _>, key_type<map<>, _> >::type type; }; int main(void) { replaceit< vector< charm pair_type<int, int_<32> >, pair_type<long, int_<64> > double > >::type toprint; std::cout << typeid(toprint).name() << std::endl; return(0); }; I know this is incorrect because the pairs will be replaced by the key_type metafunction itself. If I add ::type to the end of key_type<map<>, _> the compiler complains that no ::first member exists: boost-1_32/boost/mpl/pair.hpp: In instantiation of `boost::mpl::first<mpl_::_>': replace.cc:25: instantiated from `boost::mpl::key_type_impl<boost::mpl::aux::map_tag>::apply<boost::mpl::map<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, mpl_::_>' replace.cc:25: instantiated from `boost::mpl::key_type<boost::mpl::map<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, mpl_::_>' replace.cc:25: instantiated from here boost-1_32/boost/mpl/pair.hpp:43: no type named `first' in `struct mpl_::_' What's the right way to do this? Furthermore, is there a better way to identify pairs in replace_if than deriving from a special class? All I can think of is writing a predicate class and specializing it for mpl::pair<U, V>. Seems like there should be an easier way. Thanks! -Dave

David Greene wrote:
You should be seeing a syntax error right here.
What's the right way to do this?
Use an algorithm like transform that _computes_ the new values rather than simply replacing them with a constant value: template <class Seq> struct replaceit : transform< Seq , if_< is_base_and_derived<pair_base,_> , key_type<map<>,_> , _ > > {};
Why? That seems like a pretty darned good approach to me. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
:) I'll admit I had to patch something up in the e-mail. Obviously I mistyped.
Ok, thanks. I have to read some more to better understand which algorithms operate on constants and which invoke metafunctions. I should have been clued in by the name to look up the STL version.
I guess it didn't feel like the "mpl way" to me. I remember back when MPL was first being discussed that the STL-ness of it was compared to the pattern-matching approach of Loki. I was a doubter about the STL-ness but now that I've used it some I'm warming up to it. :) Thanks again. I'm slowly climbing the curve... -Dave
participants (2)
-
David Abrahams
-
David Greene