En plus de ce que le visiteur a dit:
La fonction void emplace_back(Type&& _Val)
fournie par MSCV10 est non conforme et redondante, car comme vous l'avez noté, elle est strictement équivalente à push_back(Type&& _Val)
.
Mais la vraie forme C ++ 0x de emplace_back
est vraiment utile void emplace_back(Args&&...)
:;
Au lieu de prendre un, value_type
il prend une liste variadique d'arguments, ce qui signifie que vous pouvez maintenant parfaitement transmettre les arguments et construire directement un objet dans un conteneur sans aucun temporaire.
C'est utile parce que, quelle que soit l'intelligence RVO et le déplacement sémantique apportés à la table, il y a encore des cas compliqués où un push_back est susceptible de faire des copies inutiles (ou de se déplacer). Par exemple, avec la insert()
fonction traditionnelle de a std::map
, vous devez créer un temporaire, qui sera ensuite copié dans un std::pair<Key, Value>
, qui sera ensuite copié dans la carte:
std::map<int, Complicated> m;
int anInt = 4;
double aDouble = 5.0;
std::string aString = "C++";
// cross your finger so that the optimizer is really good
m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString)));
// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);
Alors pourquoi n'ont-ils pas implémenté la bonne version de emplace_back dans MSVC? En fait, cela m'a trop dérangé il y a un certain temps, j'ai donc posé la même question sur le blog Visual C ++ . Voici la réponse de Stephan T Lavavej, le responsable officiel de l'implémentation de la bibliothèque standard Visual C ++ chez Microsoft.
Q: Les fonctions de mise en place de la version bêta 2 ne sont-elles qu'une sorte d'espace réservé actuellement?
R: Comme vous le savez peut-être, les modèles variadic ne sont pas implémentés dans VC10. Nous les simulons avec des machines de préprocesseur pour des choses comme le
make_shared<T>()
tuple et les nouveautés <functional>
. Cette machinerie de préprocesseur est relativement difficile à utiliser et à entretenir. En outre, cela affecte considérablement la vitesse de compilation, car nous devons inclure à plusieurs reprises des sous-titres. En raison d'une combinaison de nos contraintes de temps et de nos problèmes de vitesse de compilation, nous n'avons pas simulé de modèles variadiques dans nos fonctions d'emplace.
Lorsque des modèles variadiques sont implémentés dans le compilateur, vous pouvez vous attendre à en profiter dans les bibliothèques, y compris dans nos fonctions d'emplace. Nous prenons la conformité très au sérieux, mais malheureusement, nous ne pouvons pas tout faire en même temps.
C'est une décision compréhensible. Tous ceux qui ont essayé une seule fois d'émuler un modèle variadic avec des trucs horribles de préprocesseur savent à quel point ce truc est dégoûtant.