Além do que o visitante disse:
A função void emplace_back(Type&& _Val)
fornecida pelo MSCV10 não é conforme e é redundante, porque, como você observou, é estritamente equivalente a push_back(Type&& _Val)
.
Mas a verdadeira forma de C ++ 0x de emplace_back
é realmente útil void emplace_back(Args&&...)
:;
Em vez de pegar um, value_type
é preciso uma lista variada de argumentos, o que significa que agora você pode encaminhar perfeitamente os argumentos e construir diretamente um objeto em um contêiner sem um temporário.
Isso é útil porque, não importa quanta inteligência o RVO e a movimentação semântica tragam para a tabela, ainda existem casos complicados em que um push_back provavelmente fará cópias desnecessárias (ou mover). Por exemplo, com a insert()
função tradicional de a std::map
, você deve criar um temporário, que será copiado para a std::pair<Key, Value>
, que será copiado para o 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);
Então, por que eles não implementaram a versão correta do emplace_back no MSVC? Na verdade, isso me incomodou há um tempo atrás, então fiz a mesma pergunta no blog do Visual C ++ . Aqui está a resposta de Stephan T Lavavej, mantenedor oficial da implementação da biblioteca padrão do Visual C ++ na Microsoft.
P: As funções beta 2 emplace são apenas algum tipo de espaço reservado no momento?
R: Como você deve saber, modelos variados não são implementados no VC10. Nós os simulamos com máquinas de pré-processador para coisas como
make_shared<T>()
tupla e coisas novas <functional>
. Esse maquinário de pré-processador é relativamente difícil de usar e manter. Além disso, afeta significativamente a velocidade de compilação, pois precisamos incluir repetidamente sub-cabeçalhos. Devido a uma combinação de restrições de tempo e preocupações com a velocidade de compilação, não simulamos modelos variados em nossas funções de substituição.
Quando modelos variados são implementados no compilador, você pode esperar que possamos tirar proveito deles nas bibliotecas, inclusive em nossas funções emplace. Levamos a conformidade muito a sério, mas, infelizmente, não podemos fazer tudo de uma vez.
É uma decisão compreensível. Todo mundo que tentou apenas emular uma vez o modelo variado com truques horríveis do pré-processador sabe como essas coisas ficam nojentas.