Además de lo que dijo el visitante:
La función void emplace_back(Type&& _Val)
proporcionada por MSCV10 no es conforme y es redundante, ya que, como ha notado, es estrictamente equivalente apush_back(Type&& _Val)
.
Pero la forma real de C ++ 0x emplace_back
es realmente útil:void emplace_back(Args&&...)
:;
En lugar de tomar un value_type
, toma una lista variada de argumentos, lo que significa que ahora puede reenviar perfectamente los argumentos y construir directamente un objeto en un contenedor sin ningún tipo temporal.
Eso es útil porque no importa cuánta inteligencia RVO y movimiento semántico traigan a la mesa, todavía hay casos complicados en los que es probable que un push_back haga copias (o movimientos) innecesarios. Por ejemplo, con la insert()
función tradicional de a std::map
, debe crear un temporal, que luego se copiará en a std::pair<Key, Value>
, que luego se copiará 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);
Entonces, ¿por qué no implementaron 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 blog de Visual C ++ . Aquí está la respuesta de Stephan T Lavavej, el responsable oficial de la implementación de la biblioteca estándar de Visual C ++ en Microsoft.
P: ¿Las funciones de emplazamiento beta 2 son solo una especie de marcador de posición en este momento?
R: Como ya sabrá, las plantillas variadas no se implementan en VC10. Los simulamos con maquinaria de preprocesador para cosas como
make_shared<T>()
tuplas y cosas nuevas <functional>
. Esta maquinaria de preprocesador es relativamente difícil de usar y mantener. Además, afecta significativamente la velocidad de compilación, ya que tenemos que incluir repetidamente subencabezados. Debido a una combinación de nuestras limitaciones de tiempo y problemas de velocidad de compilación, no hemos simulado plantillas variadas en nuestras funciones de emplazamiento.
Cuando se implementan plantillas variadas en el compilador, puede esperar que las aprovechemos en las bibliotecas, incluidas nuestras funciones de ubicación. Nos tomamos muy en serio la conformidad, pero desafortunadamente no podemos hacer todo de una vez.
Es una decisión comprensible. Todos los que intentaron emular una plantilla variada con trucos horribles del preprocesador saben lo repugnante que es esto.