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

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

4 ответа

Решение
  • 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 не.

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

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

(с использованием gcc 4.7.2, повысить версию lib 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 может легко связываться с лямбда-типами C++ 11, тогда как boost::bind начиная с boost 1.54, кажется, требует ввода от пользователя (если не определен return_type). Смотрите буст док

(с использованием gcc 4.7.2, повысить версию lib 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Ваша сборка также может сломаться.

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

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

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

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

Я псевдоним пространства имен для stdph с

namespace stdph=std::placeholders;

Помимо этого у меня не было проблем с обновлением до C++11

Другие вопросы по тегам