[lamba] Comparing return value of member function with ->*
struct sample { int i; sample(int i) : i(i) { } bool odd() { return i % 2; } }; template <class T, class U> std::basic_ostream<T, U> &operator<<(std::basic_ostream<T, U>& ostr, sample s) { return ostr << s.i; } std::vector<sample> from; std::vector<sample> to; from.push_back(sample(1)); from.push_back(sample(2)); from.push_back(sample(3)); // Why doesn't this compile ... std::for_each(from.begin(), from.end(), if_then((_1 ->* &sample::odd) == false, std::cout << _1)); // ... but this does? Isn't it the same? std::for_each(from.begin(), from.end(), if_then(bind(&sample::odd, _1) == false, std::cout << _1)); Thanks in advance for any explanation which helps me to understand lamba expressions better, Boris
// Why doesn't this compile ... std::for_each(from.begin(), from.end(), if_then((_1 ->* &sample::odd) == false, std::cout << _1));
IMO it should be &1->*&sample::odd The ->* operator expects a pointer in its left side. Since & has higher priority than ->*, it suffices to add & to _l and it'll work. Regards, rod
On Tue, 13 Mar 2007 00:21:36 +0200, Rodolfo Lima <rodolfo@rodsoft.org> wrote:
// Why doesn't this compile ... std::for_each(from.begin(), from.end(), if_then((_1 ->* &sample::odd) == false, std::cout << _1));
IMO it should be &1->*&sample::odd
The ->* operator expects a pointer in its left side. Since & has higher priority than ->*, it suffices to add & to _l and it'll work.
I played around some more and even removed the comparison with false. But neither this ... std::for_each(from.begin(), from.end(), if_then(boost::lambda::_1 ->* &sample::odd, std::cout << boost::lambda::_1)); ... nor that ... std::for_each(from.begin(), from.end(), if_then(&boost::lambda::_1 ->* &sample::odd, std::cout << boost::lambda::_1)); compiles. VC8++ complains about error C2451: conditional expression of type 'boost::lambda::detail::member_pointer_caller<RET,A,B>' is illegal. Everything works though with boost::lambda::bind. Why I don't know. From the documentation ->* looks like a more readable shortcut than boost::lambda::bind. There seem to be some limitations though (or does it depend on the compiler)? Boris
Sorry, I answered your message a little too quick. Actually sample::odd is a member function, so you have to write if_then(bind(&sample::odd, _1) == false, std::cout << _1) &_1->*&sample::odd would work if sample::odd was an attribute, not a member function. Remember to use lambda's bind (i.e. boost::lambda::bind), not boost::bind. Let me know if this works. Regards, rodolfo "Boris" <boriss@web.de> escreveu na mensagem news:op.to4s8qi39dsao3@burk...
On Tue, 13 Mar 2007 00:21:36 +0200, Rodolfo Lima <rodolfo@rodsoft.org> wrote:
// Why doesn't this compile ... std::for_each(from.begin(), from.end(), if_then((_1 ->* &sample::odd) == false, std::cout << _1));
IMO it should be &1->*&sample::odd
The ->* operator expects a pointer in its left side. Since & has higher priority than ->*, it suffices to add & to _l and it'll work.
I played around some more and even removed the comparison with false. But neither this ...
std::for_each(from.begin(), from.end(), if_then(boost::lambda::_1 ->* &sample::odd, std::cout << boost::lambda::_1));
... nor that ...
std::for_each(from.begin(), from.end(), if_then(&boost::lambda::_1 ->* &sample::odd, std::cout << boost::lambda::_1));
compiles. VC8++ complains about error C2451: conditional expression of type 'boost::lambda::detail::member_pointer_caller<RET,A,B>' is illegal. Everything works though with boost::lambda::bind. Why I don't know. From the documentation ->* looks like a more readable shortcut than boost::lambda::bind. There seem to be some limitations though (or does it depend on the compiler)?
Boris
On Thu, 15 Mar 2007 01:03:38 +0200, Rodolfo Lima <rodolfo@rodsoft.org> wrote:
Sorry, I answered your message a little too quick. Actually sample::odd is a member function, so you have to write if_then(bind(&sample::odd, _1) == false, std::cout << _1)
&_1->*&sample::odd would work if sample::odd was an attribute, not a member function. Remember to use lambda's bind (i.e. boost::lambda::bind), not boost::bind.
Let me know if this works.
boost::lambda:bind works. But according to the documentation at http://www.boost.org/doc/html/lambda/le_in_details.html#lambda.operator_expr... it should be possible to use ->*, too? When you scroll down to "Member pointer operator" there is even an example where ->* is used with a member function? Boris
[...]
participants (2)
-
Boris
-
Rodolfo Lima