|
Boost Users : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-02-23 07:54:02
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. :-)
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net