
I have the following code: #include <utility> #include <boost/mpl/map.hpp> #include <boost/mpl/transform.hpp> template <typename MplPair> struct make_ptr_pair1 { typedef std::pair<typename MplPair::first *, typename MplPair::second *> type; }; template <typename First, typename Second> struct make_ptr_pair2 { typedef std::pair<First *, Second *> type; }; int main(int argc, char *argv[]) { namespace mpl = boost::mpl; typedef mpl::map< mpl::pair<int, double> > my_map; //typedef mpl::transform< my_map, make_ptr_pair1<mpl::_1> >::type ptr_pair_seq1; //typedef mpl::transform< my_map, make_ptr_pair2<mpl::_1, mpl::_2>
::type ptr_pair_seq2; return 0; }
If I uncomment any of the two mpl::transform lines in main(), the code doesn't compile (VC8). The point is to get a sequence of std::pairs out of the content of the mpl::map. Is there anything I'm doing wrong? Can mpl::transform be used for mpl::map? Maybe I can do it with fusion, but the above code seems to be something that's supposed to be working, isn't it? Yuval

Yuval Ronen writes:
I have the following code:
#include <utility> #include <boost/mpl/map.hpp> #include <boost/mpl/transform.hpp>
template <typename MplPair> struct make_ptr_pair1 { typedef std::pair<typename MplPair::first *, typename MplPair::second *> type; ^^^ mpl
};
template <typename First, typename Second> struct make_ptr_pair2 { typedef std::pair<First *, Second *> type; };
int main(int argc, char *argv[]) { namespace mpl = boost::mpl; typedef mpl::map< mpl::pair<int, double> > my_map; //typedef mpl::transform< my_map, make_ptr_pair1<mpl::_1> >::type ptr_pair_seq1; //typedef mpl::transform< my_map, make_ptr_pair2<mpl::_1, mpl::_2> >::type ptr_pair_seq2; return 0; }
If I uncomment any of the two mpl::transform lines in main(), the code doesn't compile (VC8). The point is to get a sequence of std::pairs out of the content of the mpl::map. Is there anything I'm doing wrong? Can mpl::transform be used for mpl::map?
It can be, but you need to specify the inserter manually, because the default (front_inserter, as per http://boost.org/libs/mpl/doc/refmanual/reversible-algorithm.html) is not suitable for accociated sequences: ... #include <boost/mpl/inserter.hpp> #include <boost/mpl/insert.hpp> ... int main(int argc, char *argv[]) { typedef mpl::map< mpl::pair<int, double> > my_map; typedef mpl::inserter< mpl::map0<>, mpl::insert<mpl::_1,mpl::_2> > map_inserter; typedef mpl::transform< my_map, make_ptr_pair1<mpl::_1>, map_inserter >::type ptr_pair_seq1; // ^^^^^^^^^^^^^^ return 0; }
Maybe I can do it with fusion, but the above code seems to be something that's supposed to be working, isn't it?
Yes, ideally, your original code should just work. It's a design bug. I've added the issue to the library's TODO list (http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?MPL_TODO_List). Thanks for the report, -- Aleksey Gurtovoy MetaCommunications Engineering

Aleksey Gurtovoy wrote:
Yuval Ronen writes:
I have the following code:
#include <utility> #include <boost/mpl/map.hpp> #include <boost/mpl/transform.hpp>
template <typename MplPair> struct make_ptr_pair1 { typedef std::pair<typename MplPair::first *, typename MplPair::second *> type; ^^^ mpl
I'm really puzzled about this. Why can't I have std::pair here? The whole purpose of the transform operation is to create a type-sequence of std::pairs. This sequence can be used, for example, with make_variant_over to create a variant of std::pairs. Can't I do that?
};
template <typename First, typename Second> struct make_ptr_pair2 { typedef std::pair<First *, Second *> type; };
int main(int argc, char *argv[]) { namespace mpl = boost::mpl; typedef mpl::map< mpl::pair<int, double> > my_map; //typedef mpl::transform< my_map, make_ptr_pair1<mpl::_1> >::type ptr_pair_seq1; //typedef mpl::transform< my_map, make_ptr_pair2<mpl::_1, mpl::_2> >::type ptr_pair_seq2; return 0; }
If I uncomment any of the two mpl::transform lines in main(), the code doesn't compile (VC8). The point is to get a sequence of std::pairs out of the content of the mpl::map. Is there anything I'm doing wrong? Can mpl::transform be used for mpl::map?
It can be, but you need to specify the inserter manually, because the default (front_inserter, as per http://boost.org/libs/mpl/doc/refmanual/reversible-algorithm.html) is not suitable for accociated sequences:
... #include <boost/mpl/inserter.hpp> #include <boost/mpl/insert.hpp>
...
int main(int argc, char *argv[]) { typedef mpl::map< mpl::pair<int, double> > my_map; typedef mpl::inserter< mpl::map0<>, mpl::insert<mpl::_1,mpl::_2> > map_inserter; typedef mpl::transform< my_map, make_ptr_pair1<mpl::_1>, map_inserter >::type ptr_pair_seq1; // ^^^^^^^^^^^^^^ return 0; }
Maybe I can do it with fusion, but the above code seems to be something that's supposed to be working, isn't it?
Yes, ideally, your original code should just work. It's a design bug. I've added the issue to the library's TODO list (http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?MPL_TODO_List).
Thanks for the report,
Thanks you!

Yuval Ronen wrote:
Aleksey Gurtovoy wrote:
Yuval Ronen writes:
I have the following code:
#include <utility> #include <boost/mpl/map.hpp> #include <boost/mpl/transform.hpp>
template <typename MplPair> struct make_ptr_pair1 { typedef std::pair<typename MplPair::first *, typename MplPair::second *> type; ^^^ mpl
I'm really puzzled about this. Why can't I have std::pair here? The whole purpose of the transform operation is to create a type-sequence of std::pairs. This sequence can be used, for example, with make_variant_over to create a variant of std::pairs. Can't I do that?
Ah, I think I got it. When the input to mpl::transform is a mpl::map, then it tries to generate a mpl::map as output, and therefore the need for mpl::pair. However, I don't need mpl::map as output, any Forward Sequence will suffice (as this is what make_variant_over requires). So is mpl::fold the answer here?

Yuval Ronen writes:
Yuval Ronen wrote:
Aleksey Gurtovoy wrote:
Yuval Ronen writes:
I have the following code:
#include <utility> #include <boost/mpl/map.hpp> #include <boost/mpl/transform.hpp>
template <typename MplPair> struct make_ptr_pair1 { typedef std::pair<typename MplPair::first *, typename MplPair::second *> type; ^^^ mpl
I'm really puzzled about this. Why can't I have std::pair here? The whole purpose of the transform operation is to create a type-sequence of std::pairs. This sequence can be used, for example, with make_variant_over to create a variant of std::pairs. Can't I do that?
Ah, I think I got it. When the input to mpl::transform is a mpl::map, then it tries to generate a mpl::map as output, and therefore the need for mpl::pair.
Correct.
However, I don't need mpl::map as output, any Forward Sequence will suffice (as this is what make_variant_over requires). So is mpl::fold the answer here?
No, you can still use 'transform', like this: typedef mpl::front_inserter< mpl::vector0<> > inserter; typedef mpl::transform< my_map, make_ptr_pair1<mpl::_1>, inserter >::type ptr_pair_seq1; Sorry for the late reply, -- Aleksey Gurtovoy MetaCommunications Engineering

Aleksey Gurtovoy wrote:
Yuval Ronen writes:
However, I don't need mpl::map as output, any Forward Sequence will suffice (as this is what make_variant_over requires). So is mpl::fold the answer here?
No, you can still use 'transform', like this:
typedef mpl::front_inserter< mpl::vector0<> > inserter; typedef mpl::transform< my_map, make_ptr_pair1<mpl::_1>, inserter >::type ptr_pair_seq1;
Great, thanks.
participants (2)
-
Aleksey Gurtovoy
-
Yuval Ronen