Разница между С++ 11 std:: bind и boost:: bind

Есть ли разница между этими двумя? Или я могу заменить каждое событие boost::bind на std::bind в моем коде и тем самым устранить зависимость от Boost?

Ответ 1

  • boost::bind имеет перегруженные реляционные операторы, std::bind не делает.

  • boost::bind поддерживает нестандартные соглашения о вызовах, std::bind не гарантируется (стандартные реализации библиотек могут предложить это как расширение).

  • boost::bind предоставляет прямой механизм, позволяющий предотвратить нетерпеливую оценку вложенных выражений связывания (boost::protect), std::bind нет. (Тем не менее, можно использовать boost::protect с std::bind, если они хотят, или тривиально переопределяют его сами.)

  • std::bind обеспечивает прямой механизм, позволяющий обрабатывать любой определяемый пользователем функтор как выражение вложенного связывания, чтобы заставить нетерпеливую оценку (std::is_bind_expression: [func.bind.isbind]/1, [func.bind.bind]/10), boost::bind нет.

Ответ 2

Помимо нескольких различий, указанных в других ответах, здесь есть два других отличия:

  • boost::bind, похоже, имеет дело с перегруженными именами функций в некоторых ситуациях, тогда как std::bind не работает с ними одинаково. См. С++ 11 faq

(с использованием gcc 4.7.2, boost lib version 1_54)

void foo(){}
void foo(int i){}

auto badstd1 = std::bind(foo);  
//compile error: no matching function for call to bind(<unresolved overloaded function type>)
auto badstd2 = std::bind(foo, 1); 
//compile error: no matching function for call to bind(<unresolved overloaded function type>)
auto std1 = std::bind(static_cast<void(*)()>(foo)); //compiles ok
auto std2 = std::bind(static_cast<void(*)(int)>(foo), 1); //compiles ok
auto boost1 = boost::bind(foo, 1); //compiles ok
auto boost2 = boost::bind(foo); //compiles ok

Итак, если вы просто заменили все boost::bind на std::bind, ваша сборка может сломаться.

  • std::bind может легко связываться с lambda-типами С++ 11, тогда как boost::bind с повышением 1.54, кажется, требует ввода от пользователя (если не задан параметр return_type). Подробнее см. .

(с использованием gcc 4.7.2, boost lib version 1_54)

auto fun = [](int i) { return i;};
auto stdbound = std::bind(fun, std::placeholders::_1);
stdbound(1);

auto boostboundNaive = boost::bind(fun, _1);  //compile error.
// error: no type named ‘result_type’ ...
auto boostbound1 = boost::bind<int>(fun, _1); //ok
boostbound1(1);
auto boostbound2 = boost::bind(boost::type<int>(), fun, _1); //ok
boostbound2(1);

Итак, если вы просто заменили все std::bind на boost::bind, ваша сборка также может сломаться.

Ответ 3

Помимо перечисленных выше, boost:: bind имеет важную точку расширения: get_pointer(), которая позволяет интегрировать boost:: bind с любым интеллектуальным указателем, например. ATL:: CComPtr и т.д. http://www.boost.org/doc/libs/1_49_0/libs/bind/mem_fn.html#get_pointer

В результате, с boost:: bind вы также можете привязать weak_ptr: http://lists.boost.org/Archives/boost/2012/01/189529.php

Ответ 4

У меня нет полного ответа, но std::bind будет использовать вариационные шаблоны, а не списки параметров.

Заместители находятся в std::placeholders как в std::placeholders::_1, а не в глобальном пространстве имен.

Я, как и пространство имен, в stdph с

namespace stdph=std::placeholders;

Кроме того, у меня не было проблем с обновлением до С++ 11