2012-05-11 20 views
62

Gibt es einen Unterschied zwischen den beiden? Oder bin ich sicher, jedes Auftreten von boost::bind durch std::bind in meinem Code zu ersetzen und dadurch die Abhängigkeit von Boost zu entfernen?Unterschied zwischen C++ 11 Std :: Bind und Boost :: Bind

+0

Ich glaube, 'std :: bind' wurde ziemlich viel von' boost :: bind' kopiert, als sie mit C++ 11 herauskamen, wie mit vielen anderen Dingen. – chris

+9

Die Frage bezieht sich auf den "ziemlich viel" Teil. Mit einigen der Dinge, die von Boost entfernt wurden, wurden kleinere Änderungen vorgenommen. – jalf

Antwort

84
  • boost::bindhas overloaded relational operators, tut std::bind nicht.

  • boost::bindsupports non-default calling conventions wird std::bind nicht garantiert (Standardbibliothek Implementierungen dies als Erweiterung bieten kann).

  • boost::bind einen direkten Mechanismus stellt eifrige Auswertung von verschachteltem bind Ausdrücke (boost::protect), damit einer bis verhindern, std::bind nicht. (Das heißt, man kann boost::protect mit std::bind verwenden, wenn sie wünschen, oder reimplementieren sie trivialer Weise auf ihre eigenen.)

  • std::bind einen direkten Mechanismus bereitstellt, um jeden Benutzer definiert Funktors als verschachtelte bind Expression zu erlauben, einen zu behandeln, um force eifrige Bewertung (std::is_bind_expression: [func.bind.isbind]/1, [func.bind.bind]/10), boost::bind nicht.

8

Ich habe nicht die vollständige Antwort, aber std::bind wird variadic Vorlagen anstelle von Parameterlisten verwenden. Die Platzhalter sind in std::placeholders wie in std::placeholders::_1 und nicht im globalen Namespace.

ich den Namespace Alias ​​aus mit

namespace stdph=std::placeholders; 

Apart stdph, dass ich die Aktualisierung keine Probleme mussten C 11 ++

+0

Wenn Sie vorhandenen boost :: bind-Code, der Platzhalter verwendet, portieren, fügen Sie "using namespace std :: placeholders;" Am Anfang der Datei werden die Platzhalter in den globalen Namespace eingefügt. Sehr praktisch. – goertzenator

+1

Das Problem ist, wenn Portierung Sie in der Regel mit Boost binden noch rangeln es, s Weg durch irgendwie und Sie am Ende mit dem Standard und boosten Platzhalter. – 111111

+0

Es kommt auf das Projekt an, denke ich. Ich habe alle meine Boost-Funktion mechanisch entfernt. Hpp und bind.hpp enthalten ein Projekt mit anständiger Größe und sed, und die obige Namespace-Direktive hat gut funktioniert. Wenn Sie eine Boost-Bindung in einem Header haben, den Sie nicht ändern können, sehe ich, wie die Dinge hässlich werden können. – goertzenator

16

Neben den oben aufgeführten boost :: bind hat eine wichtige Erweiterung Punkt: get_pointer() Funktion, die mit jedem Smart Pointer boost :: bind ermöglicht die Integration, beispielsweise. ATL :: CComPtr usw. http://www.boost.org/doc/libs/1_49_0/libs/bind/mem_fn.html#get_pointer

Als Ergebnis mit boost :: bind Sie auch eine weak_ptr binden können: http://lists.boost.org/Archives/boost/2012/01/189529.php

+2

Die "INVOKE" -Funktionalität im Standard funktioniert mit jedem intelligenten Zeiger, der 'operator *' unterstützt –

22

Neben den verschiedenen auf den anderen Antworten zitiert Unterschiede, hier sind zwei weitere Unterschiede:

  • boost::bind scheint mit überladenen Funktionsnamen in manchen Situationen zu bewältigen, während std::bind nicht mit ihnen in der gleichen Art und Weise befasst. Siehe c++11 faq

(mit gcc 4.7.2, steigern 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 

Also, wenn Sie einfach alle boost::bind mit std::bind ersetzt, könnte Ihr Build brechen. nahtlos binden an C++ 11 Lambda-Typen

  • std::bind kann, während boost::bind als Boost 1.54 scheint eine Eingabe vom Benutzer zu erfordern (es sei denn, Rückgabetyp ist definiert). Siehe boost doc

(mit gcc 4.7.2, steigern 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); 

Also, wenn Sie einfach alle std::bind mit boost::bind ersetzt, könnte Ihr Build auch brechen.