Opened 11 years ago

Closed 9 years ago

#5645 closed Bugs (invalid)

Problem passing lambda functor to boost::bind - code does not compile

Reported by: anonymous Owned by: Peter Dimov
Milestone: To Be Determined Component: bind
Version: Boost 1.45.0 Severity: Problem
Keywords: Cc: viboes

Description

I want to create lambda functor for function with more that 3 parameters. I need to access 1 param only, so I decided to use helper functor created wih boost::bind. Unfortunately code does not compile. But when I stored created lambda functor in boost::function object, it compiles fine.

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>

using namespace boost::lambda;

boost::lambda::placeholder1_type _l1;
boost::lambda::placeholder2_type _l2;

boost::arg<1> _b1;
boost::arg<4> _b4;

class IFoo
{
public:
    virtual ~IFoo() {}
    virtual void bar(int a, int b, int c, int d) = 0;
};

class Foo : public IFoo
{
public:
    boost::function<void(int, int, int, int)> bar_hook;
    
    void bar(int a, int b, int c, int d)
    {
        if (bar_hook)
            bar_hook(a, b, c, d);
    }
};

int main()
{
    Foo foo;
    int a = -1;
    
    // This works fine
    boost::function<void(int, int)> tmp_func = (_l2, var(a) = _l1);
    foo.bar_hook = boost::bind(tmp_func, _b1, _b4);
    
    // This fails to compile
    //foo.bar_hook = boost::bind( (_l2, var(a) = _l1), _b1, _b4 );
    
    foo.bar(1, 2, 3, 4);
    std::cout << "a = " << a << std::endl;
}

Change History (4)

comment:1 by viboes, 10 years ago

Cc: viboes added

Could you add the compiler error? With which compiler?

comment:2 by anonymous, 10 years ago

Compiler: g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)

Error message:

In file included from /path/to/boost/include/boost/bind.hpp:22,
                 from test.cc:3:
/path/to/boost/include/boost/bind/bind.hpp: In instantiation of âboost::_bi::result_traits<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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> > > >â:
/path/to/boost/include/boost/bind/bind_template.hpp:15:   instantiated from âboost::_bi::bind_t<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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::_bi::list2<boost::arg<1>, boost::arg<4> > >â
test.cc:44:   instantiated from here
/path/to/boost/include/boost/bind/bind.hpp:69: error: no type named âresult_typeâ in âclass boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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> > >â
In file included from /path/to/boost/include/boost/function/detail/maybe_include.hpp:33,
                 from /path/to/boost/include/boost/function/detail/function_iterate.hpp:14,
                 from /path/to/boost/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:67,
                 from /path/to/boost/include/boost/function.hpp:64,
                 from test.cc:4:
/path/to/boost/include/boost/function/function_template.hpp: In static member function âstatic void boost::detail::function::void_function_obj_invoker4<FunctionObj, R, T0, T1, T2, T3>::invoke(boost::detail::function::function_buffer&, T0, T1, T2, T3) [with FunctionObj = boost::_bi::bind_t<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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::_bi::list2<boost::arg<1>, boost::arg<4> > >, R = void, T0 = int, T1 = int, T2 = int, T3 = int]â:
/path/to/boost/include/boost/function/function_template.hpp:913:   instantiated from âvoid boost::function4<R, T1, T2, T3, T4>::assign_to(Functor) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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::_bi::list2<boost::arg<1>, boost::arg<4> > >, R = void, T0 = int, T1 = int, T2 = int, T3 = int]â
/path/to/boost/include/boost/function/function_template.hpp:722:   instantiated from âboost::function4<R, T1, T2, T3, T4>::function4(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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::_bi::list2<boost::arg<1>, boost::arg<4> > >, R = void, T0 = int, T1 = int, T2 = int, T3 = int]â
/path/to/boost/include/boost/function/function_template.hpp:1064:   instantiated from âboost::function<R(T0, T1, T2, T3)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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::_bi::list2<boost::arg<1>, boost::arg<4> > >, R = void, T0 = int, T1 = int, T2 = int, T3 = int]â
/path/to/boost/include/boost/function/function_template.hpp:1105:   instantiated from âtypename boost::enable_if_c<boost::type_traits::ice_not::value, boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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::_bi::list2<boost::arg<1>, boost::arg<4> > >, R = void, T0 = int, T1 = int, T2 = int, T3 = int]â
test.cc:44:   instantiated from here
/path/to/boost/include/boost/function/function_template.hpp:153: error: no match for call to â(boost::_bi::bind_t<boost::_bi::unspecified, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::comma_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::placeholder<2> >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<boost::lambda::assignment_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::identity<int&> >, 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::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::_bi::list2<boost::arg<1>, boost::arg<4> > >) (int&, int&, int&, int&)â

comment:3 by SirZooro <daniel@…>, 10 years ago

boost 1.53.0 still has this problem.

comment:4 by Peter Dimov, 9 years ago

Resolution: invalid
Status: newclosed

Use foo.bar_hook = boost::bind<void>( (_l2, var(a) = _l1), _b1, _b4 );

Note: See TracTickets for help on using tickets.