std::bind a bound function
std::bind
expressions, like their boost::bind
predecessors, support a type of composition operation. Your expression for w
is roughly equivalent to
auto w=std::bind(some_fun, std::bind(&foo::bar<int>, x, std::placeholders::_1) );
Nesting binds in this manner is interpreted as
- Calculate the value of
x.bar<int>(y)
wherey
is the first parameter passed into the resulting functor. - Pass that result into
some_fun
.
But x.bar<int>(y)
returns void, not any function type. That's why this doesn't compile.
As K-ballo points out, with boost::bind
, you can fix this problem with boost::protect
. As Kerrek SB and ildjarn point out, one way around this issue is: don't use auto
for f
. You don't want f
to have the type of a bind expression. If f
has some other type, then std::bind
won't attempt to apply the function composition rules. You might, for instance, give f
the type std::function<void(int)>
:
std::function<void(int)> f = std::bind(&foo::bar<int>, x, std::placeholders::_1);
auto w = std::bind(some_fun, f);
Since f
doesn't literally have the type of a bind expression, std::is_bind_expression<>::value
will be false on f
's type, and so the std::bind
expression in the second line will just pass the value on verbatim, rather than attempting to apply the function composition rules.