[lambda] "Invalid use of void expression"

I'm having some trouble with BLL and Boost.Function in this simple testcase: #include <boost/lambda/bind.hpp> #include <boost/function.hpp> #include <iostream> class Test { public: void foo(int a) { std::cout << "a is " << a << std::endl; }; }; template<typename Function> class Caller { private: Function func; public: Caller(Function f) : func(f) {}; void bar(void) { func(); }; }; int main(void) { Test tester; int value = 10; Caller<boost::function<void (void)> > printer(boost::lambda::bind(boost::lambda::bind(&Test::foo, tester, boost::lambda::_1), value)); printer.bar(); return(0); } The g++ 4.0.3 compiler complains (full trace below): /usr/include/boost/lambda/detail/lambda_functor_base.hpp:408: error: invalid use of void expression Is it not legal to bind a lambda-bound function? -Dave ---------------------- /usr/include/boost/lambda/detail/lambda_functor_base.hpp: In member function 'RET boost::lambda::lambda_functor_base<boost::lambda::action<2, Act>, Args>::call(A&, B&, C&, Env&) const [with RET = boost::tuples::null_type, A = const boost::tuples::null_type, B = const boost::tuples::null_type, C = const boost::tuples::null_type, Env = const boost::tuples::null_type, Act = boost::lambda::function_action<2, boost::lambda::detail::unspecified>, Args = boost::tuples::tuple<const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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>]': /usr/include/boost/lambda/detail/lambda_functors.hpp:140: instantiated from 'typename T::sig<boost::tuples::null_type>::type boost::lambda::lambda_functor<Base>::operator()() const [with T = boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> >]' /usr/include/boost/function/function_template.hpp:136: instantiated from 'static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::any_pointer) [with FunctionObj = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void]' /usr/include/boost/function/function_template.hpp:479: instantiated from 'void boost::function0<R, Allocator>::assign_to(FunctionObj, boost::detail::function::function_obj_tag) [with FunctionObj = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:430: instantiated from 'void boost::function0<R, Allocator>::assign_to(Functor) [with Functor = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:294: instantiated from 'boost::function0<R, Allocator>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:637: instantiated from 'boost::function<R ()(), Allocator>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' lambda3.cc:27: instantiated from here /usr/include/boost/lambda/detail/lambda_functor_base.hpp:408: error: invalid use of void expression /usr/include/boost/lambda/detail/actions.hpp: In static member function 'static RET boost::lambda::function_action<3, T>::apply(A1&, A2&, A3&) [with RET = void, A1 = void (Test::* const)(int), A2 = const Test, A3 = const boost::tuples::null_type, T = boost::lambda::detail::unspecified]': /usr/include/boost/lambda/detail/lambda_functor_base.hpp:425: instantiated from 'RET boost::lambda::lambda_functor_base<boost::lambda::action<3, Act>, Args>::call(A&, B&, C&, Env&) const [with RET = void, A = const boost::tuples::null_type, B = const boost::tuples::null_type, C = const boost::tuples::null_type, Env = const boost::tuples::null_type, Act = boost::lambda::function_action<3, boost::lambda::detail::unspecified>, Args = boost::tuples::tuple<void (Test::* const)(int), const Test, 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>]' /usr/include/boost/lambda/detail/select_functions.hpp:61: instantiated from 'static RET boost::lambda::detail::r_select<RET>::go(const boost::lambda::lambda_functor<Arg>&, A&, B&, C&, Env&) [with Arg = boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> >, A = const boost::tuples::null_type, B = const boost::tuples::null_type, C = const boost::tuples::null_type, Env = const boost::tuples::null_type, RET = void]' /usr/include/boost/lambda/detail/lambda_functor_base.hpp:408: instantiated from 'RET boost::lambda::lambda_functor_base<boost::lambda::action<2, Act>, Args>::call(A&, B&, C&, Env&) const [with RET = boost::tuples::null_type, A = const boost::tuples::null_type, B = const boost::tuples::null_type, C = const boost::tuples::null_type, Env = const boost::tuples::null_type, Act = boost::lambda::function_action<2, boost::lambda::detail::unspecified>, Args = boost::tuples::tuple<const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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>]' /usr/include/boost/lambda/detail/lambda_functors.hpp:140: instantiated from 'typename T::sig<boost::tuples::null_type>::type boost::lambda::lambda_functor<Base>::operator()() const [with T = boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> >]' /usr/include/boost/function/function_template.hpp:136: instantiated from 'static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::any_pointer) [with FunctionObj = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void]' /usr/include/boost/function/function_template.hpp:479: instantiated from 'void boost::function0<R, Allocator>::assign_to(FunctionObj, boost::detail::function::function_obj_tag) [with FunctionObj = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:430: instantiated from 'void boost::function0<R, Allocator>::assign_to(Functor) [with Functor = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:294: instantiated from 'boost::function0<R, Allocator>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:637: instantiated from 'boost::function<R ()(), Allocator>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = 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::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const Test, 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> > >, const int, 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> > >, R = void, Allocator = std::allocator<void>]' lambda3.cc:27: instantiated from here /usr/include/boost/lambda/detail/actions.hpp:96: error: no matching function for call to 'boost::lambda::function_adaptor<void (Test::*)(int)>::apply(void (Test::* const&)(int), const Test&, const boost::tuples::null_type&)' /usr/include/boost/lambda/detail/function_adaptors.hpp:245: note: candidates are: static Result boost::lambda::function_adaptor<Result (Object::*)(Arg1)>::apply(Result (Object::*)(Arg1), Object*, A1&) [with RET = void, A1 = const boost::tuples::null_type, Object = Test, Arg1 = int, Result = void] /usr/include/boost/lambda/detail/function_adaptors.hpp:249: note: static Result boost::lambda::function_adaptor<Result (Object::*)(Arg1)>::apply(Result (Object::*)(Arg1), Object&, A1&) [with RET = void, A1 = const boost::tuples::null_type, Object = Test, Arg1 = int, Result = void] /usr/include/boost/lambda/detail/actions.hpp:96: error: return-statement with a value, in function returning 'void'

David A. Greene wrote:
I'm having some trouble with BLL and Boost.Function in this simple testcase:
I worked around the problem using Boost.Function: int main(void) { Test tester; int value = 10; boost::function<void (int)> bound = boost::lambda::bind(&Test::foo, &tester, boost::lambda::_1); Caller<boost::function<void (void)> > printer(boost::lambda::bind(bound, value)); //Caller<boost::function<void (void)> > printer(boost::lambda::bind(boost::lambda::bind(&Test::foo, &tester, boost::lambda::_1), value)); printer.bar(); return(0); } I have a couple of questions and another problem, however. I had to pass "&tester" to the first bind expression because g++ complained about passing "tester" as "const Test &." Is passing by reference supposed to work? Also, this workaround gets rid of the error but is the original code supposed to work as written or did I do something incorrectly? Finally, the new problem, closer to the actual code I'm working with: #include <boost/lambda/bind.hpp> #include <boost/function.hpp> #include <boost/shared_ptr.hpp> #include <iostream> class Test { public: void foo(int a) { std::cout << "a is " << a << std::endl; }; }; template<typename Function> class Caller { private: Function func; public: Caller(Function f) : func(f) {}; void bar(void) { func(); }; }; int main(void) { boost::shared_ptr<Test> tester(new Test); int value = 10; boost::function<void (int)> bound = boost::lambda::bind(&Test::foo, tester, boost::lambda::_1); Caller<boost::function<void (void)> > printer(boost::lambda::bind(bound, value)); printer.bar(); return(0); } g++ comaplains (full trace below): lambda4.cc:28: instantiated from here /usr/include/boost/lambda/detail/actions.hpp:96: error: no matching function for call to 'boost::lambda::function_adaptor<void (Test::*)(int)>::apply(void (Test::* const&)(int), const boost::shared_ptr<Test>&, int&)' /usr/include/boost/lambda/detail/function_adaptors.hpp:245: note: candidates are: static Result boost::lambda::function_adaptor<Result (Object::*)(Arg1)>::apply(Result (Object::*)(Arg1), Object*, A1&) [with RET = void, A1 = int, Object = Test, Arg1 = int, Result = void] /usr/include/boost/lambda/detail/function_adaptors.hpp:249: note: static Result boost::lambda::function_adaptor<Result (Object::*)(Arg1)>::apply(Result (Object::*)(Arg1), Object&, A1&) [with RET = void, A1 = int, Object = Test, Arg1 = int, Result = void] /usr/include/boost/lambda/detail/actions.hpp:96: error: return-statement with a value, in function returning 'void' Any ideas? I'd rather not use .get() because of the potential deallocation that might happen out from under the bound function. -Dave -------------------- /usr/include/boost/lambda/detail/actions.hpp: In static member function 'static RET boost::lambda::function_action<3, T>::apply(A1&, A2&, A3&) [with RET = void, A1 = void (Test::* const)(int), A2 = const boost::shared_ptr<Test>, A3 = int, T = boost::lambda::detail::unspecified]': /usr/include/boost/lambda/detail/lambda_functor_base.hpp:425: instantiated from 'RET boost::lambda::lambda_functor_base<boost::lambda::action<3, Act>, Args>::call(A&, B&, C&, Env&) const [with RET = void, A = int, B = const boost::tuples::null_type, C = const boost::tuples::null_type, Env = const boost::tuples::null_type, Act = boost::lambda::function_action<3, boost::lambda::detail::unspecified>, Args = boost::tuples::tuple<void (Test::* const)(int), const boost::shared_ptr<Test>, 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>]' /usr/include/boost/lambda/detail/lambda_functors.hpp:148: instantiated from 'typename T::sig<boost::tuples::tuple<A&, 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::tuples::null_type> >::type boost::lambda::lambda_functor<Base>::operator()(A&) const [with A = int, T = boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const boost::shared_ptr<Test>, 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> >]' /usr/include/boost/function/function_template.hpp:136: instantiated from 'static void boost::detail::function::void_function_obj_invoker1<FunctionObj, R, T0>::invoke(boost::detail::function::any_pointer, T0) [with FunctionObj = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const boost::shared_ptr<Test>, 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> > >, R = void, T0 = int]' /usr/include/boost/function/function_template.hpp:479: instantiated from 'void boost::function1<R, T0, Allocator>::assign_to(FunctionObj, boost::detail::function::function_obj_tag) [with FunctionObj = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const boost::shared_ptr<Test>, 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> > >, R = void, T0 = int, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:430: instantiated from 'void boost::function1<R, T0, Allocator>::assign_to(Functor) [with Functor = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const boost::shared_ptr<Test>, 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> > >, R = void, T0 = int, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:294: instantiated from 'boost::function1<R, T0, Allocator>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const boost::shared_ptr<Test>, 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> > >, R = void, T0 = int, Allocator = std::allocator<void>]' /usr/include/boost/function/function_template.hpp:637: instantiated from 'boost::function<R ()(T0), Allocator>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3, boost::lambda::function_action<3, boost::lambda::detail::unspecified> >, boost::tuples::tuple<void (Test::* const)(int), const boost::shared_ptr<Test>, 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> > >, R = void, T0 = int, Allocator = std::allocator<void>]' lambda4.cc:28: instantiated from here /usr/include/boost/lambda/detail/actions.hpp:96: error: no matching function for call to 'boost::lambda::function_adaptor<void (Test::*)(int)>::apply(void (Test::* const&)(int), const boost::shared_ptr<Test>&, int&)' /usr/include/boost/lambda/detail/function_adaptors.hpp:245: note: candidates are: static Result boost::lambda::function_adaptor<Result (Object::*)(Arg1)>::apply(Result (Object::*)(Arg1), Object*, A1&) [with RET = void, A1 = int, Object = Test, Arg1 = int, Result = void] /usr/include/boost/lambda/detail/function_adaptors.hpp:249: note: static Result boost::lambda::function_adaptor<Result (Object::*)(Arg1)>::apply(Result (Object::*)(Arg1), Object&, A1&) [with RET = void, A1 = int, Object = Test, Arg1 = int, Result = void] /usr/include/boost/lambda/detail/actions.hpp:96: error: return-statement with a value, in function returning 'void'

On 1/24/06, David A. Greene <greened@obbligato.org> wrote:
David A. Greene wrote:
I'm having some trouble with BLL and Boost.Function in this simple testcase:
I worked around the problem using Boost.Function:
int main(void) { Test tester; int value = 10;
boost::function<void (int)> bound = boost::lambda::bind(&Test::foo, &tester, boost::lambda::_1); Caller<boost::function<void (void)> > printer(boost::lambda::bind(bound, value)); //Caller<boost::function<void (void)> > printer(boost::lambda::bind(boost::lambda::bind(&Test::foo, &tester, boost::lambda::_1), value));
printer.bar();
return(0); }
I have a couple of questions and another problem, however.
I had to pass "&tester" to the first bind expression because g++ complained about passing "tester" as "const Test &." Is passing by reference supposed to work?
Only if you use a reference wrapper - i.e. you can use boost::ref(tester) or boost::lambda::var(tester) rather than &tester
Also, this workaround gets rid of the error but is the original code supposed to work as written or did I do something incorrectly?
Finally, the new problem, closer to the actual code I'm working with:
#include <boost/lambda/bind.hpp> #include <boost/function.hpp> #include <boost/shared_ptr.hpp>
#include <iostream>
class Test { public: void foo(int a) { std::cout << "a is " << a << std::endl; }; };
template<typename Function> class Caller { private: Function func;
public: Caller(Function f) : func(f) {};
void bar(void) { func(); }; };
int main(void) { boost::shared_ptr<Test> tester(new Test); int value = 10;
boost::function<void (int)> bound = boost::lambda::bind(&Test::foo, tester, boost::lambda::_1); Caller<boost::function<void (void)> > printer(boost::lambda::bind(bound, value));
printer.bar();
return(0); }
If you're using a shared_ptr, you'll either need to use tester.get() directly to get a Test* to pass into the bind expression bind(&Test::foo, tester.get(), value) or something like bind(&Test::foo, bind(boost::shared_ptr<Test>::get, tester), value) to delay the call to tester.get() until invocation of printer.bar(). Stuart Dootson

Stuart Dootson wrote:
I had to pass "&tester" to the first bind expression because g++ complained about passing "tester" as "const Test &." Is passing by reference supposed to work?
Only if you use a reference wrapper - i.e. you can use boost::ref(tester) or boost::lambda::var(tester) rather than &tester
The documentation is misleading, then: The object argument can be a reference or pointer to the object, the BLL supports both cases with a uniform interface: bool A::foo(int) const; A a; vector<int> ints; ... find_if(ints.begin(), ints.end(), bind(&A::foo, a, _1)); find_if(ints.begin(), ints.end(), bind(&A::foo, &a, _1));
If you're using a shared_ptr, you'll either need to use tester.get() directly to get a Test* to pass into the bind expression
bind(&Test::foo, tester.get(), value)
or something like
bind(&Test::foo, bind(boost::shared_ptr<Test>::get, tester), value)
to delay the call to tester.get() until invocation of printer.bar().
Yuck. Oh well, guess that's what I'll do. Are there any plans to add direct support for smart pointers? -Dave

On 1/24/06, David A. Greene <greened@obbligato.org> wrote:
Stuart Dootson wrote:
<snip/>
Yuck. Oh well, guess that's what I'll do. Are there any plans to add direct support for smart pointers?
-Dave
I seem to remember that boost::bind (as opposed to boost::lambda::bind) supports boost::shared_ptr directly...so if you only need the bind bit of lambda, switch to boost::bind Stuart

On 1/24/06, David A. Greene <greened@obbligato.org> wrote:
I'm having some trouble with BLL and Boost.Function in this simple testcase:
#include <boost/lambda/bind.hpp> #include <boost/function.hpp>
#include <iostream>
class Test { public: void foo(int a) { std::cout << "a is " << a << std::endl; }; };
template<typename Function> class Caller { private: Function func;
public: Caller(Function f) : func(f) {};
void bar(void) { func(); }; };
int main(void) { Test tester; int value = 10;
Caller<boost::function<void (void)> > printer(boost::lambda::bind(boost::lambda::bind(&Test::foo, tester, boost::lambda::_1), value));
printer.bar();
return(0); }
The g++ 4.0.3 compiler complains (full trace below):
/usr/include/boost/lambda/detail/lambda_functor_base.hpp:408: error: invalid use of void expression
Is it not legal to bind a lambda-bound function?
-Dave
It's probably more that it makes the compilers job too difficult...anyway - I think you'll find that one of these two does what you want (I've assumed a 'using namespace boost::lambda;' because it declutters the code): Caller<boost::function<void ()> > printer1(bind(&Test::foo, &tester, value)); Caller<boost::function<void ()> > printer1(bind(&Test::foo, &tester, boost::ref(value))); With printer1, the value of 'value' is baked into the bound object. With printer2, a reference to 'value' is baked into the bound object. This means that if you change the value of 'value', printer1 won't reflect the change, but printer2 will - the following code printer1.bar(); printer2.bar(); value = 1234; printer1.bar(); printer2.bar(); will give the output 10 10 10 1234 HTH! Stuart Dootson
participants (2)
-
David A. Greene
-
Stuart Dootson