if_then_else_return (boost::lambda) question

Greetings! I'm fairly new to boost and have a little problem with if_then_else_return. Can anyone tell me the problem with the following short program? [It seems that my 'thenBranch' and 'elseBranch' functions are never called and if_then_else_return' always returns true (as if the 'then' branch were called)]. Many thanks in advance for any help you may offer! P.S. (A more general C++ q: A little improvement I'd like to make is to drop the ITERATORTYPE type argument from IfNotEndThenElseReturn and use CONTAINERTYPE::iterator instead, but the compiler won't allow that. Anyone know why?). Thanks again! ============================================ #include <boost/lambda/lambda.hpp> #include <boost/lambda/if.hpp> #include <boost/lambda/bind.hpp> #include <boost/function.hpp> #include <functional> #include <list> using namespace boost::lambda; template<typename RET> RET InvokeReturn(boost::function<void ()> f, const RET& retVal) { printf("in InvokeReturn!\n"); f(); return retVal; } bool InvokeReturnTrue(boost::function<void ()> f) { return InvokeReturn(f, true); } bool InvokeReturnFalse(boost::function<void ()> f) { return InvokeReturn(f, false); } boost::function<bool ()> MakeReturnTrue(boost::function<void ()> f) { printf("in MakeReturnTrue!\n"); return boost::lambda::bind(&InvokeReturnTrue, f); } boost::function<bool ()> MakeReturnFalse(boost::function<void ()> f) { printf("in MakeReturnFalse!\n"); return boost::lambda::bind(&InvokeReturnFalse, f); } template<typename CONTAINERTYPE, typename ITERATORTYPE> bool IfNotEndThenElseReturn(const ITERATORTYPE& it, CONTAINERTYPE& container, boost::function<void ()> thenBranch, boost::function<void ()> elseBranch) { printf("in IfNotEndThenElseReturn!\n"); std::not_equal_to<ITERATORTYPE> ne; return boost::lambda::if_then_else_return( boost::lambda::bind(&std::not_equal_to<ITERATORTYPE>::operator(), ne, it, container.end()), MakeReturnTrue(thenBranch), MakeReturnFalse(elseBranch))(); } void thenBranch() { printf("in then branch!\n"); } void elseBranch() { printf("in else branch!\n"); } int _tmain(int argc, _TCHAR* argv[]) { printf("beginning execution!\n"); std::list<int> l; l.push_back(8); l.push_back(7); l.push_back(6); l.push_back(5); std::list<int>::iterator it = l.end(); std::list<int>::iterator it2 = l.begin(); bool b = IfNotEndThenElseReturn(it, l, bind(&thenBranch), bind(&elseBranch)); printf("b is %s\n", b ? "true" : "false"); bool b = IfNotEndThenElseReturn(it2, l, bind(&thenBranch), bind(&elseBranch)); printf("b is %s\n", b ? "true" : "false"); printf("finished!\n"); return 0; }

AMDG Jonathan Leonard wrote:
I'm fairly new to boost and have a little problem with if_then_else_return. Can anyone tell me the problem with the following short program? [It seems that my 'thenBranch' and 'elseBranch' functions are never called and if_then_else_return' always returns true (as if the 'then' branch were called)].
The problem is that Boost.Lambda doesn't automatically call the boost::function. Thus, evaluating the lambda expression returns a boost::function, boost::function implicitly converts to bool. (false iff the boost::function is empty.) If you use boost::lambda::bind(MakeReturnTrue(thenBranch)), it should work.
P.S. (A more general C++ q: A little improvement I'd like to make is to drop the ITERATORTYPE type argument from IfNotEndThenElseReturn and use CONTAINERTYPE::iterator instead, but the compiler won't allow that. Anyone know why?). Thanks again!
typename CONTAINERTYPE::iterator works for me. Did you forget typename? In Christ, Steven Watanabe

Steven Watanabe wrote:
Jonathan Leonard wrote:
I'm fairly new to boost and have a little problem with if_then_else_return. Can anyone tell me the problem with the following short program? [It seems that my 'thenBranch' and 'elseBranch' functions are never called and if_then_else_return' always returns true (as if the 'then' branch were called)].
The problem is that Boost.Lambda doesn't automatically call the boost::function. Thus, evaluating the lambda expression returns a boost::function, boost::function implicitly converts to bool. (false iff the boost::function is empty.) If you use boost::lambda::bind(MakeReturnTrue(thenBranch)), it should work.
Awesome! That indeed does work.
P.S. (A more general C++ q: A little improvement I'd like to make is to drop the ITERATORTYPE type argument from IfNotEndThenElseReturn and use CONTAINERTYPE::iterator instead, but the compiler won't allow that. Anyone know why?). Thanks again!
typename CONTAINERTYPE::iterator works for me. Did you forget typename?
Yep. Thank you!
participants (2)
-
Jonathan Leonard
-
Steven Watanabe