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

  1. Calculate the value of x.bar<int>(y) where y is the first parameter passed into the resulting functor.
  2. 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.