Marius Herzog
Marius Herzog

Reputation: 597

std::bind yields compilation error in libstdc++

The following piece of code compiles without problems:

void dimse_pm::f()
{
       ul.inject(upperlayer::TYPE::A_ASSOCIATE_RQ,
           [=](upperlayer::scx* sc, std::unique_ptr<upperlayer::property> rq) { 
               associate(sc, std::move(rq)); 
            } 
       );
}

However, the following code using std::bind fails to compile.

void dimse_pm::f()
{
    using namespace std::placeholders;
    ul.inject(upperlayer::TYPE::A_ASSOCIATE_RQ,
         std::bind(&dimse_pm::associate, this, _1));
}

This is the error I get:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/include/g++-v4/functional:1925:2: error: no matching function for call to     object of type 'std::_Bind<std::_Mem_fn<void (dimse_pm::*)(upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >)> (dimse_pm *, std::_Placeholder<1>)>'
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/include/g++-v4/functional:2298:33: note: in instantiation of member function  'std::_Function_handler<void (upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >), std::_Bind<std::_Mem_fn<void (dimse_pm::*)(upperlayer::scx *,  std::unique_ptr<upperlayer::property, std::default_delete<upperlayer::property> >)>
  (dimse_pm *, std::_Placeholder<1>)> >::_M_invoke' requested here
        _M_invoker = &_My_handler::_M_invoke;
                                   ^
dimse_pm.cpp:25:14: note: in instantiation of function template specialization 'std::function<void (upperlayer::scx *, std::unique_ptr<upperlayer::property, std::default_delete<upperlayer::property>
  >)>::function<std::_Bind<std::_Mem_fn<void (dimse_pm::*)(upperlayer::scx *, std::unique_ptr<upperlayer::property, std::default_delete<upperlayer::property> >)> (dimse_pm *, std::_Placeholder<1>)> >' requested here
         std::bind(&dimse_pm::associate, this, _1));
         ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/include/g++-v4/functional:1211:2: note: candidate template ignored: substitution failure [with _Args = <upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >>]: no matching function for call to object of type 'std::_Mem_fn<void (dimse_pm::*)(upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >)>'
    operator()(_Args&&... __args)
    ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/include/g++-v4/functional:1225:2: note: candidate template ignored: substitution failure [with _Args = <upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >>]: no matching function for call to object of type 'const std::_Mem_fn<void (dimse_pm::*)(upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >)>'
    operator()(_Args&&... __args) const
    ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/include/g++-v4/functional:1239:2: note: candidate template ignored: substitution failure [with _Args = <upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >>]: no matching function for call to object of type 'volatile std::_Mem_fn<void (dimse_pm::*)(upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >)>'
    operator()(_Args&&... __args) volatile
    ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/include/g++-v4/functional:1253:2: note: candidate template ignored: substitution failure [with _Args = <upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >>]: no matching function for call to object of type 'const volatile std::_Mem_fn<void (dimse_pm::*)(upperlayer::scx *, std::unique_ptr<upperlayer::property,
  std::default_delete<upperlayer::property> >)>'
    operator()(_Args&&... __args) const volatile

associate is a member function of dimse_pm and not overloaded. The object ul on which the inject function is called, stores std::function<void(scx*, std::unique_ptr<property>)>. I want to get rid of the this-pointer. This error happens with both clang 3.5 and gcc 4.7.3.

Upvotes: 0

Views: 247

Answers (1)

Oktalist
Oktalist

Reputation: 14714

[=](upperlayer::scx* sc, std::unique_ptr<upperlayer::property> rq) { 
     associate(sc, std::move(rq)); 
}

This lambda function object calls associate with two arguments (upperlayer::scx* and std::unique_ptr<upperlayer::property>&&) plus the this pointer.

std::bind(&dimse_pm::associate, this, _1)

This bind expression object calls associate with one argument plus the this pointer, which fails because associate expects two arguments plus the this pointer.

What you want is this:

std::bind(&dimse_pm::associate, this, _1, _2)

this, _1, _2 means that this will be captured and forwarded as the implicit this argument to associate, the first argument to the bind expression's call operator will be forwarded as the first explicit argument to associate and the second argument to the bind expression's call operator will be forwarded as the second explicit argument to associate.

Upvotes: 3

Related Questions