Hi Folks, Can anyone tell me why this is wrong? My intention is to call A::f() for each A constructed on-the-fly from the elements of v. Thanks, Rob. #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/construct.hpp> #include <algorithm> #include <vector> struct A { A( int ); void f( ); }; int main( ) { using namespace boost::lambda; std::vector< int > v; std::for_each( v.begin( ), v.end( ), bind( & A::f, bind( constructor<A>(), _1 ) ) ); }
Hi! This one works... #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/construct.hpp> #include <algorithm> #include <vector> struct A { A(int) {} void f()const {} }; int main( ) { using namespace boost::lambda; std::vector< int > v; std::for_each( v.begin( ), v.end(), bind(&A::f, bind<A>(constructor<A>(), _1))); } Regards, Ovanes On Tue, Mar 23, 2010 at 6:41 PM, Robert Jones <robertgbjones@gmail.com>wrote:
Hi Folks,
Can anyone tell me why this is wrong? My intention is to call A::f() for each A constructed on-the-fly from the elements of v.
Thanks, Rob.
#include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/construct.hpp> #include <algorithm> #include <vector>
struct A { A( int ); void f( ); };
int main( ) { using namespace boost::lambda;
std::vector< int > v; std::for_each( v.begin( ), v.end( ), bind( & A::f, bind( constructor<A>(), _1 ) ) ); }
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On Tue, Mar 23, 2010 at 6:02 PM, Ovanes Markarian <om_boost@keywallet.com>wrote:
Hi!
This one works...
#include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/construct.hpp> #include <algorithm> #include <vector>
struct A { A(int) {} void f()const {} };
int main( ) { using namespace boost::lambda;
std::vector< int > v; std::for_each( v.begin( ), v.end(), bind(&A::f, bind<A>(constructor<A>(), _1))); }
It does indeed, making method f() const fixes it, but I still can't quite see why. Without the constness of f() the guts of the error says this, /usr/include/boost/lambda/detail/actions.hpp:87: error: no matching function for call to ‘boost::lambda::function_adaptor<void (A::*)()>::apply(void (A::* const&)(), const A&)’ from which it seems that the constructed required signature includes a const A&. Why is this? - Rob.
On Wed, Mar 24, 2010 at 9:38 AM, Robert Jones <robertgbjones@gmail.com>wrote:
It does indeed, making method f() const fixes it, but I still can't quite see why. Without the constness of f() the guts of the error says this,
/usr/include/boost/lambda/detail/actions.hpp:87: error: no matching function for call to ‘boost::lambda::function_adaptor<void (A::*)()>::apply(void (A::* const&)(), const A&)’
from which it seems that the constructed required signature includes a const A&. Why is this?
Because A() is an rvalue, a temporary which cannot be assigned to a non-const reference. What you propose is pretty equal to the following ill-formed construct: void do_smth(A& a) { // do smth. } do_smth(A(7)); So the best boost::bind overload which compiler finds is that which accepts A const& => only const members are allowed to be accessed. Regards, Ovanes
On Wed, Mar 24, 2010 at 9:19 AM, Ovanes Markarian <om_boost@keywallet.com>wrote:
void do_smth(A& a) { // do smth. }
do_smth(A(7));
So the best boost::bind overload which compiler finds is that which accepts A const& => only const members are allowed to be accessed.
Yes, I constructed an equivalent example, and then couldn't see the wood for the trees! Ok, I know I'm having an aberrant moment here, but remind me why a temporary can't be passed as a non-const reference. - Rob.
On Wed, Mar 24, 2010 at 11:29 AM, Robert Jones <robertgbjones@gmail.com>wrote:
On Wed, Mar 24, 2010 at 9:19 AM, Ovanes Markarian <om_boost@keywallet.com>wrote:
Ok, I know I'm having an aberrant moment here, but remind me why a temporary can't be passed as a non-const reference.
Because ISO C++ Standard 2003 prohibits it and explicitly states that the lifetime of a temporary can be extended when it is bound to a const-reference. I don't know the exact paragraph, nor have the access to the Standard right now, but I clearly remember having read it. There is even an example how long the temporary lives when bound to the const-reference. The situation will change with the moving semantics and rvalue references in the upcoming standard C++0x. If you really need to modify the internal object state you could introduce mutable data members. Those can be changed from const-qualified member functions. But think twice if you really need it... Getting back to the previous example the code looks as: #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/construct.hpp> #include <algorithm> #include <vector> struct A { A(int i) : i_(i) {} void f()const { i_ = 20; } private: mutable int i_; }; int main( ) { using namespace boost::lambda; std::vector< int > v; std::for_each( v.begin( ), v.end(), bind(&A::f, bind<A>(constructor<A>(), _1))); } Regards, Ovanes
Robert Jones wrote:
Hi Folks,
Can anyone tell me why this is wrong? My intention is to call A::f() for each A constructed on-the-fly from the elements of v.
Thanks, Rob.
Hi Rob - Since I'm promoting phoenix these days (o; Here is one way you could do it -------------------- #include <iostream> #include <vector> #include <boost/spirit/include/phoenix.hpp> struct A { A( int i ) : i_( i ) {} void f(){ std::cout << i_ << std::endl; } int i_; }; int main() { using namespace boost::phoenix; using namespace boost::phoenix::arg_names; using namespace boost::phoenix::local_names; std::vector< int > vec; // fill the vector with something for( int i=0; i < 10; ++i ) { vec.push_back( i ); } // create an A for each vector entry std::for_each( vec.begin(), vec.end(), let( _a = construct<A>(arg1) ) [ bind( &A::f, _a ) ] ); return 0; } ------------------------------------------------ And now say we want to do something a little more interesting ... like store the newly constructed object in a vector also. #include <iostream> #include <vector> #include <boost/spirit/include/phoenix.hpp> struct A { A( int i ) : i_( i ) {} void f(){ std::cout << i_ << std::endl; } int i_; }; int main() { using namespace boost::phoenix; using namespace boost::phoenix::arg_names; using namespace boost::phoenix::local_names; std::vector< int > vec; std::vector< A > a_vec; // fill the vector with something for( int i=0; i < 10; ++i ) { vec.push_back( i ); } // create an A for each vector entry, call f() // on the object and store it in a vector std::for_each( vec.begin(), vec.end(), let( _a = construct<A>(arg1) ) [ bind( &A::f, _a ), push_back( ref(a_vec), _a ) ] ); // print out our vector of A's using a phoenix bind // to a member variable std::for_each( a_vec.begin(), a_vec.end(), ( std::cout << bind( &A::i_, arg1) << " " ) ); return 0; } ------------------------------------------------ Write the "push_back" for bind/lambda ... you will see why phoenix is so much nicer to look at. michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com
participants (3)
-
Michael Caisse
-
Ovanes Markarian
-
Robert Jones