Y a-t-il une différence entre les deux? Ou suis-je sûr de remplacer chaque occurrence de boost::bind
par std::bind
dans mon code et ainsi me débarrasser de toute dépendance à Boost?
Réponses
Trop de publicités?boost::bind
a subi une surcharge d'opérateurs relationnels,std::bind
ne le sont pas.boost::bind
prise en charge non par défaut de conventions d'appel,std::bind
n'est pas garantie (bibliothèque standard implémentations peuvent offrir cela comme une extension).boost::bind
fournit un mécanisme direct, afin de permettre à prévenir désireux d'évaluation de imbriquée lier expressions,std::bind
ne le sont pas. (Cela dit, on peut utiliserboost::protect
avecstd::bind
si ils le veulent, ou trivialement reproduire à leur propre compte.)std::bind
fournit un mécanisme direct, afin de permettre de traiter n'importe quel utilisateur défini comme un foncteur imbriquée lier l'expression dans l'ordre à la force désireux d'évaluation (§20.8.9.1.1/1, §20.8.9.1.2/10),boost::bind
ne le sont pas.
Outre les nombreuses différences citées dans les autres réponses, voici deux autres différences:
-
boost::bind
semble traiter avec surcharge des noms de fonction dans certaines situations, alors que l'std::bind
ne les traite pas de la même manière. Voir la faq c++11
(à l'aide de gcc 4.7.2, lib boost 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
Donc, si vous suffit de remplacer tous boost::bind
avec std::bind
, votre construction pourrait se casser.
-
std::bind
peut parfaitement se lier à c++11 lambda types, alors queboost::bind
de boost 1.54 semble exiger la saisie de l'utilisateur (sauf si return_type est défini). Voir la doc de boost
(à l'aide de gcc 4.7.2, lib boost 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);
Donc, si vous avez simplement remplacé tous std::bind
avec boost::bind
, votre construction peut aussi rompre.
En plus de la liste ci-dessus, boost::bind a un important point d'extension: get_pointer() fonction qui permet d'intégrer boost::bind avec le smart pointeur, par exemple. ATL::CComPtr etc. http://www.boost.org/doc/libs/1_49_0/libs/bind/mem_fn.html#get_pointer
En conséquence, avec boost::bind vous pouvez également lier un weak: http://lists.boost.org/Archives/boost/2012/01/189529.php
Je n'ai pas la réponse complète, mais std::bind
utilisera des modèles variadiques plutôt que des listes de paramètres.
Les espaces réservés sont exprimés en std::placeholders
tant que std::placeholders::_1
plutôt qu'en un espace de noms global.
J'alias l'espace de noms à stdph avec
namespace stdph=std::placeholders;
En dehors de cela, je n'ai pas eu de problèmes de mise à jour vers C ++ 11