2012-05-11 19 views
62

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

+0

Credo che 'std :: bind' sia stato copiato da' boost :: bind' quando sono usciti con C++ 11, come con molte altre cose. – chris

+9

La domanda riguarda comunque la parte "praticamente". Con alcune delle cose che sono state rimosse da Boost, sono state apportate modifiche minori. – jalf

risposta

84
  • boost::bindhas overloaded relational operators, std::bind non lo fa.

  • non è garantito a (le implementazioni di libreria standard possono offrire questo come un'estensione).

  • boost::bind fornisce un meccanismo diretto a permettere di prevenire valutazione desiderosi di espressioni nidificate bind (boost::protect), std::bind non lo fa. (Detto questo, si può usare boost::protect con std::bind se vogliono, o banalmente reimplementare da soli.)

  • std::bind fornisce un meccanismo diretto a consentire di trattare qualsiasi funtore definito dall'utente come espressione bind nidificato al fine di force valutazione stimolante (std::is_bind_expression: [func.bind.isbind]/1, [func.bind.bind]/10), boost::bind no.

8

Non ho la risposta completa ma std::bind utilizzerà modelli variadic anziché elenchi di parametri.

I segnaposto sono in std::placeholders come in std::placeholders::_1 anziché lo spazio dei nomi globale.

ho alias lo spazio dei nomi per stdph con

namespace stdph=std::placeholders; 

A parte che non ho avuto problemi l'aggiornamento a C++ 11

+0

Durante il porting di boost :: codice di bind che utilizza segnaposti, aggiungendo "using namespace std :: placeholders;" nella parte superiore del file mette i segnaposto nello spazio dei nomi globale. Molto maneggevole. – goertzenator

+1

il problema è che quando si esegue il porting di solito si finisce con il boost bind che ancora lo blocca, in qualche modo si finisce e si finisce con lo standard e si aumentano i segnaposto. – 111111

+0

Dipende dal progetto che immagino. Ho rimosso meccanicamente tutte le mie funzioni boost.hpp e bind.hpp da un progetto di dimensioni discrete con sed e la direttiva namespace di cui sopra ha funzionato bene. Se hai un bind di potenziamento in un'intestazione che non puoi cambiare, vedo come le cose potrebbero diventare brutte. – goertzenator

16

Oltre elencati sopra, boost :: bind ha un importante punto di estensione: get_pointer() funzione che permette 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 è anche possibile associare un weak_ptr: http://lists.boost.org/Archives/boost/2012/01/189529.php

+2

La funzionalità 'INVOKE' nello standard funziona con qualsiasi puntatore intelligente che supporta l'operatore' ' –

22

Oltre alle molte differenze citate sulle altre risposte, qui ci sono altre due differenze:

  • boost::bind sembra a che fare con i nomi delle funzioni sovraccarico in alcune situazioni, mentre std::bind non tratta con loro nello stesso modo. Vedi c++11 faq

(usando gcc 4.7.2, aumentare la versione 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 

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

  • std::bind può senza legarsi a C++ 11 tipi lambda, mentre boost::bind come di spinta 1.54 sembra richiedere l'input dell'utente (a meno che non sia definito return_type). Vedi boost doc

(usando gcc 4.7.2, aumentare la versione 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); 

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

Problemi correlati