Differenza tra C ++ 11 std :: bind e boost :: bind

C’è qualche differenza tra i due? O sono sicuro di sostituire ogni occorrenza di boost::bind da std::bind nel mio codice e quindi rimuovere la dipendenza da Boost?

  • boost::bind ha sovraccaricato gli operatori relazionali , std::bind no.

  • boost::bind supporta le convenzioni di chiamata non predefinite , std::bind non è garantito (le implementazioni di libreria standard potrebbero offrire questa estensione).

  • boost::bind fornisce un meccanismo diretto per consentire a una persona di evitare la valutazione appassionata delle espressioni di binding annidate ( boost::protect ), std::bind no. (Ciò detto, si può usare boost::protect con std::bind se lo desiderano, o banalmente reimplementarlo da soli.)

  • std::bind fornisce un meccanismo diretto che consente di trattare qualsiasi funtore definito dall’utente come espressione di binding nidificata per forzare la valutazione ( std::is_bind_expression : [func.bind.isbind] / 1, [func.bind.bind ] / 10), boost::bind no.

Oltre alle diverse differenze citate sulle altre risposte, ecco altre due differenze:

  • boost::bind sembra trattare con nomi di funzioni sovraccarichi in alcune situazioni, mentre std::bind non li tratta allo stesso modo. Vedi c ++ 11 faq

(usando gcc 4.7.2, potenzia la versione 1_54 della lib)

 void foo(){} void foo(int i){} auto badstd1 = std::bind(foo); //compile error: no matching function for call to bind() auto badstd2 = std::bind(foo, 1); //compile error: no matching function for call to bind() auto std1 = std::bind(static_cast(foo)); //compiles ok auto std2 = std::bind(static_cast(foo), 1); //compiles ok auto boost1 = boost::bind(foo, 1); //compiles ok auto boost2 = boost::bind(foo); //compiles ok 

Quindi, se hai semplicemente sostituito tutti gli boost::bind con std::bind , la tua build potrebbe rompersi.

  • std::bind può std::bind perfettamente ai tipi di lambda c ++ 11, mentre boost::bind come boost 1.54 sembra richiedere input dall’utente (a meno che non sia definito return_type). Vedi boost doc

(usando gcc 4.7.2, potenzia la versione 1_54 della lib)

 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(fun, _1); //ok boostbound1(1); auto boostbound2 = boost::bind(boost::type(), fun, _1); //ok boostbound2(1); 

Quindi, se hai semplicemente sostituito tutti std::bind con boost::bind , la tua build potrebbe anche rompersi.

Oltre a quanto sopra elencato, boost :: bind ha un importante punto di estensione: funzione get_pointer () che consente di integrare boost :: bind con qualsiasi puntatore intelligente, ad es. ATL :: CComPtr ecc. http://www.boost.org/doc/libs/1_49_0/libs/bind/mem_fn.html#get_pointer

Di conseguenza, con boost :: bind puoi anche associare un weak_ptr: http://lists.boost.org/Archives/boost/2012/01/189529.php

Non ho la risposta completa ma std::bind userà modelli variadici piuttosto che liste di parametri.

I segnaposti sono in std::placeholders come in std::placeholders::_1 anziché nel namespace globale.

Alias ​​lo spazio dei nomi su cui scrivere stdph

 namespace stdph=std::placeholders; 

A parte questo, non ho avuto problemi con l’aggiornamento a C ++ 11