
Hi, I just tried to use boost::lambda to prevent from creating an extra Functor class just for one call. This is the code I tried: std::deque<LightningSlice>::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), boost::lambda::_1.timeslice().contains(time_) ); with typedef std::deque<LightningSlice> LightningQueue; LightningQueue m_lightnings; //!< The lightnings in timeslices const boost::posix_time::time_period& LightningSlice::timeslice() const { return this->m_period; } Then I get the error: ../LightningIndex.cpp:38: error: 'const struct boost::lambda::lambda_functor<boost::lambda::placeholder<1> >' has no member named 'timeslice' What did I wrong? Thanks, Sven

On 03/30/2012 07:19 PM, Sven Bauhan wrote:
Hi,
I just tried to use boost::lambda to prevent from creating an extra Functor class just for one call. This is the code I tried:
std::deque<LightningSlice>::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), boost::lambda::_1.timeslice().contains(time_) );
with typedef std::deque<LightningSlice> LightningQueue; LightningQueue m_lightnings; //!< The lightnings in timeslices
const boost::posix_time::time_period& LightningSlice::timeslice() const { return this->m_period; }
Then I get the error: ../LightningIndex.cpp:38: error: 'const struct boost::lambda::lambda_functor<boost::lambda::placeholder<1> >' has no member named 'timeslice'
What did I wrong?
The type of the placeholder is completely different from the type the placeholder will be eventually be replaced with. This in fact could be any type in the world. What you need to do is bind it: bind( // We want to bind the result of the innermost bind to another // function &boost::posix_time::time_period::contains , bind( // We want to bind the timeslice function to the first argument // passed &LightningQueue::timeslice , _1 ) ) The flavor of bind you want to use is not important. There are currently 3 possibilities in boost (and a 4th if you use C++11): http://www.boost.org/doc/libs/release/libs/bind/ http://www.boost.org/doc/libs/1_49_0/doc/html/lambda/le_in_details.html#lamb... http://boost-sandbox.sourceforge.net/libs/phoenix/doc/html/phoenix/modules/b... Boost.Bind is really just to bind functions. Lambda and Phoenix allow to build more sophisticated unnamed functions. Phoenix is the newest incarnation.
Thanks, Sven _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 30.03.2012, at 19:19, Sven Bauhan wrote:
Hi,
I just tried to use boost::lambda to prevent from creating an extra Functor class just for one call. This is the code I tried:
std::deque<LightningSlice>::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), boost::lambda::_1.timeslice().contains(time_) );
with typedef std::deque<LightningSlice> LightningQueue; LightningQueue m_lightnings; //!< The lightnings in timeslices
const boost::posix_time::time_period& LightningSlice::timeslice() const { return this->m_period; }
Then I get the error: ../LightningIndex.cpp:38: error: 'const struct boost::lambda::lambda_functor<boost::lambda::placeholder<1> >' has no member named 'timeslice'
What did I wrong?
Calling member functions doesn't work that way with lambdas. You have to use boost::lambda::bind. http://www.boost.org/doc/libs/1_49_0/doc/html/lambda/le_in_details.html#lamb... So for your code: namespace ll = boost::lambda; ... = std::find_if(..., ll::bind(&Timeslice::contains, ll::bind(&LightningSlice::timeslice, ll::_1), time_)); Yes, it's ugly. Unfortunately, you can't really improve on it. Sebastian

namespace ll = boost::lambda; ... = std::find_if(..., ll::bind(&Timeslice::contains, ll::bind(&LightningSlice::timeslice, ll::_1), time_));
Yes, it's ugly. Unfortunately, you can't really improve on it.
Sebastian _______________________________________________
Thanks, I tried this suggestion: #include <boost/lambda/bind.hpp> namespace ll = boost::lambda; LightningQueue::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), bind( &boost::posix_time::time_period::contains, ll::bind( &LightningSlice::timeslice, ll::_1 ), time_ ) ); But then I got this error message: ../LightningIndex.cpp: In member function 'weather::LightningSlice weather::LightningIndex::getLightningSlice(boost::posix_time::ptime)': ../LightningIndex.cpp:40: error: no matching function for call to 'bind(<unresolved overloaded function type>, const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<const boost::posix_time::time_period& (weather::LightningSlice::* const)()const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, boost::posix_time::ptime&)' This is even more confusion than the first error message. Greetings, Sven

----- Mail original -----
De: "Sven Bauhan" <sven.bauhan@ast.dfs.de> À: boost-users@lists.boost.org Envoyé: Lundi 2 Avril 2012 09:52:38 Objet: Re: [Boost-users] Lambda and placeholders
namespace ll = boost::lambda; ... = std::find_if(..., ll::bind(&Timeslice::contains, ll::bind(&LightningSlice::timeslice, ll::_1), time_));
Yes, it's ugly. Unfortunately, you can't really improve on it.
Sebastian _______________________________________________
Thanks,
I tried this suggestion:
#include <boost/lambda/bind.hpp> namespace ll = boost::lambda;
LightningQueue::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), bind( &boost::posix_time::time_period::contains, ll::bind( &LightningSlice::timeslice, ll::_1 ), time_ ) );
But then I got this error message:
"error: no matching function for call to 'bind'" Your first "bind" is not "ll::"-prefixed. Regards, Ivan
../LightningIndex.cpp: In member function 'weather::LightningSlice weather::LightningIndex::getLightningSlice(boost::posix_time::ptime)': ../LightningIndex.cpp:40: error: no matching function for call to 'bind(<unresolved overloaded function type>, const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified>
, boost::tuples::tuple<const boost::posix_time::time_period& (weather::LightningSlice::* const)()const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, boost::posix_time::ptime&)'
This is even more confusion than the first error message.
Greetings, Sven _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 04/02/2012 09:52 AM, Sven Bauhan wrote:
namespace ll = boost::lambda; ... = std::find_if(..., ll::bind(&Timeslice::contains, ll::bind(&LightningSlice::timeslice, ll::_1), time_));
Yes, it's ugly. Unfortunately, you can't really improve on it.
Sebastian _______________________________________________ Thanks,
I tried this suggestion:
#include<boost/lambda/bind.hpp> namespace ll = boost::lambda;
LightningQueue::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), bind(&boost::posix_time::time_period::contains, ll::bind(&LightningSlice::timeslice, ll::_1 ), time_ ) );
But then I got this error message:
../LightningIndex.cpp: In member function 'weather::LightningSlice weather::LightningIndex::getLightningSlice(boost::posix_time::ptime)': ../LightningIndex.cpp:40: error: no matching function for call to 'bind(<unresolved overloaded function type>, const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<const boost::posix_time::time_period& (weather::LightningSlice::* const)()const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, boost::posix_time::ptime&)'
This is even more confusion than the first error message. The problem is that boost::posix_time::time_period::contains is overloaded. Thus the compiler can not decide which function address you mean. The solution I usually go with is the following:
bool (boost::posix_time::time_period::*f)(boost::posix_time::time_period const &) const = &boost::posix_time::time_period::contains; or: bool (boost::posix_time::time_period::*f)(boost::posix_time::ptime const &) const = &boost::posix_time::time_period::contains; Depending on what type time_ actually is ... and then continue with: LightningQueue::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), bind(f, ll::bind(&LightningSlice::timeslice, ll::_1 ), time_ ) );
Greetings, Sven _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On Monday, 2. April 2012 13:12:30 Thomas Heller wrote:
The problem is that boost::posix_time::time_period::contains is overloaded. Thus the compiler can not decide which function address you mean. The solution I usually go with is the following:
bool (boost::posix_time::time_period::*f)(boost::posix_time::time_period const &) const = &boost::posix_time::time_period::contains;
or:
bool (boost::posix_time::time_period::*f)(boost::posix_time::ptime const &) const = &boost::posix_time::time_period::contains;
Depending on what type time_ actually is ...
and then continue with:
LightningQueue::const_iterator l = std::find_if( m_lightnings.begin(), m_lightnings.end(), bind(f, ll::bind(&LightningSlice::timeslice, ll::_1 ), time_ ) );
Thanks, this works now. But I think I need a lot of comments for the next code reviewer to understand it. Greetings, Sven
participants (4)
-
ivan.lelann@free.fr
-
Sebastian Redl
-
Sven Bauhan
-
Thomas Heller