hello, I don't have much experience with boost, so I'm having problems getting boost lambda to work...hope someone here can point me in the right direction. I have: class Song {public: string artist( ) const { return m_artist } string title( ) const { return m_title } private: string m_artist, m_title; } typedef boost::shared_ptr<Song> pSong; vector<pSong> c; and I am trying to use lambda to find a song in c which matches a certain artist and title...something like iterator it = find_if( c.begin(), c.end(), something ) but I havn't figured out what "something" should look like I've tried find_if(begin(),end(), (_1->artist() == "a1" && _1->title = "t1" ) ); but the compiler -- or I =) -- doesn't seem to know the type of _1 --> error: base operand of `->' has non-pointer type `const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >' If I try it = find_if(begin(),end(), boost::bind(&Song::artist,_1) == "a1" ); it fails because "_1" is ambiguos (defined as lambda/placeholder and boost/arg ) using boost::lambda::bind (and not including the "normal" bind ) gives a bunch cryptic errors... I've tried several other variants with lambda / lambda::bind / boost::bind but I havn't figured it out... can anyone help me out? I'd also like to know what's the difference between boost::bind and boost::lambda::bind ? Also... is there a way to know when a lambda object is going to be constructed?, it's probably just that I don't know much about the BLL, but in cases where you have several nested lambdas and binds, I'm not sure which lambda objects will get constructed. regards, luis
and I am trying to use lambda to find a song in c which matches a certain artist and title... .... If I try it = find_if(begin(),end(), boost::bind(&Song::artist,_1) == "a1" ); it fails because "_1" is ambiguos (defined as lambda/placeholder and boost/arg )
using boost::lambda::bind (and not including the "normal" bind ) gives a bunch cryptic errors...
That looks correct (but I'm no expert); could it be a problem with using "a1" directly? Does something like this work: #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> using namespace boost::lambda; String a1("a1"); it = find_if(begin(),end(), bind(&Song::artist,_1) == a1 );
I'd also like to know what's the difference between boost::bind and boost::lambda::bind ?
My understanding was the boost::lambda is a superset of bind functionality, so if the lambda library works on your compiler then you should use that. Darren
Luis De la Parra wrote:
hello, I don't have much experience with boost, so I'm having problems getting boost lambda to work...hope someone here can point me in the right direction.
I have: class Song {public: string artist( ) const { return m_artist } string title( ) const { return m_title } private: string m_artist, m_title; } typedef boost::shared_ptr<Song> pSong; vector<pSong> c;
and I am trying to use lambda to find a song in c which matches a certain artist and title...something like
iterator it = find_if( c.begin(), c.end(), something )
but I havn't figured out what "something" should look like
I've tried find_if(begin(),end(), (_1->artist() == "a1" && _1->title = "t1" ) ); but the compiler -- or I =) -- doesn't seem to know the type of _1 --> error: base operand of `->' has non-pointer type `const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >'
If I try it = find_if(begin(),end(), boost::bind(&Song::artist,_1) == "a1" ); it fails because "_1" is ambiguos (defined as lambda/placeholder and boost/arg )
using boost::lambda::bind (and not including the "normal" bind ) gives a bunch cryptic errors...
You're almost there. The problem is that lambda::bind (proudly) does not support shared_ptr as a first 'this' argument, as boost::bind does. So you have to dereference it first: it = find_if(c.begin(), c.end(), bind(&Song::artist, *_1) == "a1"); Alas, this doesn't work either, because Lambda cannot dereference a shared_ptr. To make it work, you will have to patch your <boost/lambda/detail/operator_return_type_traits.hpp> header a bit. First, find the portion that says // A is a nonreference type template <class A> struct contentsof_type { typedef typename std::iterator_traits<A>::reference type; }; and change the typedef line to read typedef typename boost::indirect_reference<A>::type type; Now add #include "boost/indirect_reference.hpp" somewhere at the top, and now this program should compile: #include <boost/shared_ptr.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> using namespace boost::lambda; #include <string> #include <vector> #include <algorithm> class Song { public: std::string artist( ) const { return m_artist; } std::string title( ) const { return m_title; } private: std::string m_artist, m_title; }; typedef boost::shared_ptr<Song> pSong; std::vector<pSong> c; int main() { std::find_if( c.begin(), c.end(), bind(&Song::artist, *_1) == "a1" && bind(&Song::artist, *_1) == "t1" ); } Well, it does for me. :-)
hi, first of all thanx for the quick response...I didn't have much time in the past days, but now I'm trying to get this to work.... On Monday 23 February 2004 13:54, Peter Dimov wrote:
First, find the portion that says
// A is a nonreference type template <class A> struct contentsof_type { typedef typename std::iterator_traits<A>::reference type; };
and change the typedef line to read
typedef typename boost::indirect_reference<A>::type type;
Now add
#include "boost/indirect_reference.hpp"
but I'm missing the indirect_reference.hpp file... the file is not there, and searching in all files in boost/ for indirect_reference resulted in no matches... can you tell me where I can find it? I'm using boost 1.30.2 ... installed from rpms in suse 9.0 thank you luis
Luis De la Parra wrote:
Now add
#include "boost/indirect_reference.hpp"
but I'm missing the indirect_reference.hpp file... the file is not there, and searching in all files in boost/ for indirect_reference resulted in no matches...
can you tell me where I can find it? I'm using boost 1.30.2 ... installed from rpms in suse 9.0
It's a new addition in 1.31, sorry.
participants (3)
-
Darren Cook
-
Luis De la Parra
-
Peter Dimov