Collin Dauphinee
Collin Dauphinee

Reputation: 14003

Why is this std::bind not converted to std::function?

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

Answers (1)

Jesse Good
Jesse Good

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

Related Questions