[lambda & range] bind for transformed - how to do it.

In this code (fabricated) sequence, ages_by_bind compiles, but ages_by_lambda does not. I believe this is because the lambda version does not publish result_type to its resultant functors, since the increased generality of lambda makes this difficult or impossible to do. Is there any way I can get round this, as it currently makes the lambda/transformed combination completely unusable AFAICS. Thx, - Rob. #include <map> #include <vector> #include <string> #include <boost/bind.hpp> #include <boost/range.hpp> #include <boost/range/adaptor/transformed.hpp> #include <boost/range/algorithm_ext/push_back.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> std::vector<int> ages_by_bind( const std::map<std::string, int> & people ) { using boost::adaptors::transformed; std::vector<int> result; boost::range::push_back( result, people | transformed( bind( & std::map<std::string, int>::value_type::second, _1 ) ) ); return result; } std::vector<int> ages_by_lambda( const std::map<std::string, int> & people ) { using boost::adaptors::transformed; namespace ll = boost::lambda; std::vector<int> result; boost::range::push_back( result, people | transformed( ll::bind( & std::map<std::string, int>::value_type::second, ll::_1 ) ) ); return result; }

On 29 November 2011 13:09, Robert Jones <robertgbjones@gmail.com> wrote:
In this code (fabricated) sequence, ages_by_bind compiles, but ages_by_lambda does not.
I believe this is because the lambda version does not publish result_type to its resultant functors, since the increased generality of lambda makes this difficult or impossible to do.
Is there any way I can get round this, as it currently makes the lambda/transformed combination completely unusable AFAICS.
Have you tried using Phoenix? It has better support for result_type.

On Tue, Nov 29, 2011 at 1:30 PM, Daniel James <dnljms@gmail.com> wrote:
On 29 November 2011 13:09, Robert Jones <robertgbjones@gmail.com> wrote:
In this code (fabricated) sequence, ages_by_bind compiles, but ages_by_lambda does not.
I believe this is because the lambda version does not publish result_type to its resultant functors, since the increased generality of lambda makes this difficult or impossible to do.
Is there any way I can get round this, as it currently makes the lambda/transformed combination completely unusable AFAICS.
Have you tried using Phoenix? It has better support for result_type.
I have now, precisely because I'd understood it had better support as you said. Like this, perhaps someone could tell me if this is fine on 1.44/1.47 too! Thx, - Rob. #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/home/phoenix/bind.hpp> #include <boost/spirit/home/phoenix/core/argument.hpp> std::vector<int> ages_by_phoenix( const std::map<std::string, int> & people ) { namespace ph = boost::phoenix; namespace arg = boost::phoenix::arg_names; using boost::adaptors::transformed; std::vector<int> result; boost::range::push_back( result, people | transformed( ph::bind( & std::map<std::string, int>::value_type::second, arg::_1 ) ) ); return result; }

Robert Jones wrote:
I believe this is because the lambda version does not publish result_type to its resultant functors, since the increased generality of lambda makes this difficult or impossible to do.
What version of Boost do you use? Boost.Lambda has supported result_of since Boost 1.44. Your code compiles fine with the trunk version of Boost. Regards, Michel

On Tue, Nov 29, 2011 at 1:43 PM, Michel Morin <mimomorin@gmail.com> wrote:
Robert Jones wrote:
I believe this is because the lambda version does not publish result_type to its resultant functors, since the increased generality of lambda makes this difficult or impossible to do.
What version of Boost do you use? Boost.Lambda has supported result_of since Boost 1.44.
Your code compiles fine with the trunk version of Boost.
:( 1.41, piffle!
Thx for the info tho'. - Rob.

On 29.11.2011 17:09, Robert Jones wrote:
In this code (fabricated) sequence, ages_by_bind compiles, but ages_by_lambda does not.
I believe this is because the lambda version does not publish result_type to its resultant functors, since the increased generality of lambda makes this difficult or impossible to do.
Is there any way I can get round this, as it currently makes the lambda/transformed combination completely unusable AFAICS. Visual Studio 2010 SP1 (with boost from trunk) compiles this code. I suppose 1.48 will be ok too. BTW, why using bind or even lambda? There is a more simpler way:
#include <boost/range/iterator_range_core.hpp> #include <boost/range/adaptor/map.hpp> std::vector<int> ages(const std::map<std::string, int>& people) { using boost::adaptors::map_values; return boost::copy_range<std::vector<int> >(people | map_values); }
participants (4)
-
Daniel James
-
Michel Morin
-
Robert Jones
-
Sam Fisher