Neil G
Neil G

Reputation: 33282

functional, bind1st and mem_fun

Why won't this compile?

#include <functional> 
#include <boost/function.hpp> 

class A { 
    A() { 
        typedef boost::function<void ()> FunctionCall; 
        FunctionCall f = std::bind1st(std::mem_fun(&A::process), this); 
    } 
    void process() {} 
};

Errors:

In file included from /opt/local/include/gcc44/c++/bits/stl_function.h:712,
                 from /opt/local/include/gcc44/c++/functional:50,
                 from a.cc:1:
/opt/local/include/gcc44/c++/backward/binders.h: In instantiation of 'std::binder1st<std::mem_fun_t<void, A> >':
a.cc:7:   instantiated from here
/opt/local/include/gcc44/c++/backward/binders.h:100: error: no type named 'second_argument_type' in 'class std::mem_fun_t<void, A>'
/opt/local/include/gcc44/c++/backward/binders.h:103: error: no type named 'first_argument_type' in 'class std::mem_fun_t<void, A>'
/opt/local/include/gcc44/c++/backward/binders.h:106: error: no type named 'first_argument_type' in 'class std::mem_fun_t<void, A>'
/opt/local/include/gcc44/c++/backward/binders.h:111: error: no type named 'second_argument_type' in 'class std::mem_fun_t<void, A>'
/opt/local/include/gcc44/c++/backward/binders.h:117: error: no type named 'second_argument_type' in 'class std::mem_fun_t<void, A>'
/opt/local/include/gcc44/c++/backward/binders.h: In function 'std::binder1st<_Operation> std::bind1st(const _Operation&, const _Tp&) [with _Operation = std::mem_fun_t<void, A>, _Tp = A*]':
a.cc:7:   instantiated from here
/opt/local/include/gcc44/c++/backward/binders.h:126: error: no type named 'first_argument_type' in 'class std::mem_fun_t<void, A>'
In file included from /opt/local/include/boost/function/detail/maybe_include.hpp:13,
                 from /opt/local/include/boost/function/detail/function_iterate.hpp:14,
                 from /opt/local/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47,
                 from /opt/local/include/boost/function.hpp:64,
                 from a.cc:2:
/opt/local/include/boost/function/function_template.hpp: In static member function 'static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = std::binder1st<std::mem_fun_t<void, A> >, R = void]':
/opt/local/include/boost/function/function_template.hpp:913:   instantiated from 'void boost::function0<R>::assign_to(Functor) [with Functor = std::binder1st<std::mem_fun_t<void, A> >, R = void]'
/opt/local/include/boost/function/function_template.hpp:722:   instantiated from 'boost::function0<R>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = std::binder1st<std::mem_fun_t<void, A> >, R = void]'
/opt/local/include/boost/function/function_template.hpp:1064:   instantiated from 'boost::function<R()>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = std::binder1st<std::mem_fun_t<void, A> >, R = void]'
a.cc:7:   instantiated from here
/opt/local/include/boost/function/function_template.hpp:153: error: no match for call to '(std::binder1st<std::mem_fun_t<void, A> >) ()'

Upvotes: 4

Views: 3121

Answers (1)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507343

Because bind1st requires a binary function object. However you pass an unary function object. The function object binders of C++03 aren't as sophisticated as the one found in boost or tr1. In fact, they suffer from basic problems like not being able to handle functions with reference parameters.

Since you already use boost, i recommend to use boost::bind

FunctionCall f = boost::bind(&A::process, this); // yay!

Upvotes: 7

Related Questions