Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2008-02-04 13:02:57


David Sankel:

...

> class T
> {
> public:
> char m_c;
> T( char c ) : m_c( c )
> {
> }
> virtual T * clone() const=0;
> virtual ~T(){}
> };
> typedef boost::shared_ptr<T> TPtr;
> typedef std::vector<TPtr> TVec;
> using namespace boost::lambda;
>
> This works:
>
> const boost::function< void( T const * const) > f =
> bind( &TVec::push_back, &tVec,
> bind( constructor<TPtr>(),
> bind( &T::clone, _1)));
>
> But this doesn't:
>
> const boost::function< void( const T & ) > g =
> bind( &TVec::push_back, &tVec,
> bind( constructor<TPtr>(),
> bind( &T::clone, boost::cref(_1) )));

Note that cref(_1) isn't valid; the parameters are already taken by
reference, _1 should suffice.

> The compilation error I'm getting is that it cannot create a new
> object of type T and that is expected since T is abstract. Why would
> lambda be making copies instead of passing on the reference?

This is a known Lambda bug; internally, it tries to create the type tuple<T,
_1_type> and fails. If you add

template<class T> struct constructor
{
    typedef T result_type;

    template<class A1> T operator()( A1 const & a1 ) const
    {
        return T( a1 );
    }
};

you can compile the above with boost::bind, although a better solution would
probably be to rewrite it with a loop. :-)


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