Además de lo visitante dijo:
La función void emplace_back(Type&& _Val)
proporcionada por MSCV10 es no conforme y redundante, ya que como se anotó, es estrictamente equivalente a push_back(Type&& _Val)
.
Pero la verdadera forma C++ 0x de emplace_back
es realmente útil: void emplace_back(Args&&...)
;
En lugar de tomar un value_type
, se necesita una lista variada de argumentos, de modo que ahora puede reenviar perfectamente los argumentos y construir directamente un objeto en un contenedor sin ningún tipo de temporal.
Eso es útil, ya que no importa cuánta astucia RVO y semántica de movimientos traiga a la mesa todavía hay casos complicados en los que un push_back probablemente haga copias innecesarias (o se mueva). Por ejemplo, con el tradicional insert()
función de un std::map
, usted tiene que crear un temporal, que luego se copia en un std::pair<Key, Value>
, que luego se copia en el mapa:
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);
Así que por qué no lo hicieron implementar la versión correcta de emplace_back en MSVC? En realidad, también me molestó hace un tiempo, así que hice la misma pregunta en el Visual C++ blog. Aquí está la respuesta de Stephan T Lavavej, el mantenedor oficial de la implementación de la biblioteca estándar de Visual C++ en Microsoft.
P: ¿Las funciones de la versión beta 2 son solo algún tipo de marcador de posición en este momento?
A: Como ya sabe, las plantillas variadas no están implementadas en VC10. Nosotros simularlos con el preprocesador maquinaria para cosas como , tupla, y el nuevo cosas en <functional>
. Esta maquinaria de preprocesador es relativamente difícil de usar y mantener.Además, afecta significativamente a la velocidad de compilación , ya que tenemos que repetidamente incluir subcabeceras. Debido a una combinación de de nuestras limitaciones de tiempo y problemas de velocidad de compilación, no hemos simulado las plantillas variadicas en nuestras funciones de despliegue.
Cuando las plantillas son variadic implementado en el compilador, puede esperar que vamos a tomar ventaja de ellos en las bibliotecas, incluyendo en nuestras funciones emplace. Tomamos la conformidad muy en serio, pero lamentablemente no podemos hacer todo todos a la vez.
Es una decisión comprensible. Todos los que intentaron emular una plantilla variadic con horribles trucos de preprocesador saben lo desagradable que es esto.
Algunas buenas lecturas aquí: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2642.pdf –
Tenga en cuenta que (como dice Thomas a continuación), el código en la pregunta es de la * emulación * de MSVS de C++ 0x, no lo que realmente es C++ 0x. – me22
Un documento mejor para leer sería: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2345.pdf. N2642 es en su mayoría redacción para el estándar; N2345 es el documento que explica y motiva la idea. – Alan