Есть ли разница между этими двумя? Или я могу заменить каждое событие boost::bind
на std::bind
в моем коде и тем самым устранить зависимость от Boost?
Разница между С++ 11 std:: bind и boost:: bind
Ответ 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