Reputation: 14003
Why is the nested std::bind
in the below code not implicitly converted to an std::function<void()>
by any of the major compilers (VS2010/2012, gcc, clang)? Is this standard behavior, or a bug?
#include <functional>
void bar(int, std::function<void()>) { }
void foo() { }
int main()
{
std::function<void(int, std::function<void()>)> func;
func = std::bind(bar, 5, std::bind(foo));
std::cin.get();
return 0;
}
Upvotes: 1
Views: 1106
Reputation: 52365
This is explained in the boost documentation:
The inner bind expressions are evaluated, in unspecified order, before the outer bind when the function object is called; the results of the evaluation are then substituted in their place when the outer bind is evaluated. In the example above, when the function object is called with the argument list (x), bind(g, _1)(x) is evaluated first, yielding g(x), and then bind(f, g(x))(x) is evaluated, yielding the final result f(g(x)).
Boost even provides protect
to prevent this evaluation:
#include <boost/bind/protect.hpp>
...
func = std::bind(bar, 5, boost::protect(std::bind(foo)));
However, to call func
you have to provide both arguments like this (thanks to David Rodríguez - dribeas for pointing that out), so this example is definitely not good:
func(1, std::function<void()>());
Upvotes: 4