Difference Between C++11 Std::Bind and Boost::Bind

Difference between C++11 std::bind and boost::bind

  • boost::bind has overloaded relational operators, std::bind does not.

  • boost::bind supports non-default calling conventions, std::bind is not guaranteed to (standard library implementations may offer this as an extension).

  • boost::bind provides a direct mechanism to allow one to prevent eager evaluation of nested bind expressions (boost::protect), std::bind does not. (That said, one can use boost::protect with std::bind if they want, or trivially reimplement it on their own.)

  • std::bind provides a direct mechanism to allow one to treat any user defined functor as a nested bind expression in order to force eager evaluation (std::is_bind_expression: [func.bind.isbind]/1, [func.bind.bind]/10), boost::bind does not.

Difference between std::bind and boost::bind with polymorphism

Visual Studio 2012 has a lot of bugs relating to std::function and std::bind. This is one of them; the code will work in both Visual Studio 2010 and Visual Studio 2013.

The best choice is to use Boost.Function and Boost.Bind exclusively.

Should I be seeing significant differences between std::bind and boost::bind?

#include <functional>
namespace boost {
namespace asio {
namespace stdplaceholders {
static decltype ( :: std :: placeholders :: _1 ) & error = :: std :: placeholders :: _1;
static decltype ( :: std :: placeholders :: _2 ) & bytes_transferred = :: std :: placeholders :: _2;
static decltype ( :: std :: placeholders :: _2 ) & iterator = :: std :: placeholders :: _2;
static decltype ( :: std :: placeholders :: _2 ) & signal_number = :: std :: placeholders :: _2;
}
}
}

and use boost::asio::stdplaceholders::* instead of boost::asio::placeholders::*

Why does boost::asio::io_service not compile with std::bind?

The error message indicate that std::bind() cannot determine which io_service::run() overload to use:

std::size io_service::run();
std::size io_service::run(boost::system::error_code&);

For this particular case, Boost.Bind does not have an issue, but it does provide some troubleshooting for binding an overloaded functions. It recommends either casting:

std::bind(
static_cast<std::size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run),
&ioService);

Or using a temporary variable:

std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run;
std::bind(run, &ioService);

The reason why the explicit casting is needed for std::bind() but not boost::bind() is due to implementation details. If the arity of the call to bind() does not place constraints on the type of function being binded, then explicit casting will be required for overloaded functions.

For instance, consider the case where a variadic template is used:

template<class F, class... BoundArgs>
unspecified std::bind(F&& f, BoundArgs&&... bound_args);

When the best matching std::bind() overload is being selected, the arity of the call to std::bind() places no restrictions on F. As F could be either of the following:

  • std::size_t (boost::asio::io_service::*)()
  • std::size_t (boost::asio::io_service::*)(boost::system::error_code&)

the expression &boost::asio::io_service::run() is ambiguous.

On the other hand, Boost.Bind is implemented with overloaded functions wherein the arity of the call to boost::bind() places constraints on the arity of the function being binded. Its interface synopsis lists the following noteworthy overloads:

// 2 args: member-to-function (arity:0), instance
template <class R, class T, class A1>
unspecified bind(R (T::*f)(), A1 a1);

// 3 args: member-to-function (arity:1), instance, arg1
template <class R, class T, class B1, class A1, class A2>
unspecified bind(R (T::*f)(B1), A1 a1, A2 a2);

Note that when boost::bind() has:

  • an arity of 2, the pointer-to-member function has an arity of 0
  • an arity of 3, the pointer-to-member function has an arity of 1

Hence, when calling:

boost::bind(&boost::asio::io_service::run, &ioService)

The boost::bind() overloads that are potential matches have an arity of 2, so the pointer-to-member function must be a type of function with an arity of 0. As only a single function in the set of io_service::run() overloads has an arity of 0, the call is not ambiguous.

Chained invocation of C++11 std::bind doesn't work

The standard says that any callable can be wrapped using std::bind, including those produced by a preceding call to std::bind. Your problem is caused by a deficiency in the implementation of the standard library you're using, the solution is either to upgrade or, if this bug isn't still fixed, to switch to a different implementation.

Problem when passing as argument a std::bind of a member function on C++ (and MoveIt API)

It looks like you are mixing the Boost _1, _2, _3 placeholders with std::bind. Try one of the following:

  • Switching to boost::bind,
  • Adding using std::placeholders; right before the call,
  • Using a lambda expression that captures this.

Can intermixing std::'s and boost::'s ::bind and ::function cause problems?

No. The whole purpose of std:: (and boost::) function is that they can accept any function object which can be called with the correct signature- including lambdas, functors, and the result of any kind of binding. They do not care where your function object came from or what type it is.

You can even bind them to each other, although I'm not really sure why you'd want to.



Related Topics



Leave a reply



Submit