Boost logo

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