Selain apa yang dikatakan pengunjung:
Fungsi yang void emplace_back(Type&& _Val)
disediakan oleh MSCV10 tidak sesuai dan mubazir, karena seperti yang Anda catat, ini setara dengan push_back(Type&& _Val)
.
Tapi bentuk nyata C ++ 0x emplace_back
sangat berguna void emplace_back(Args&&...)
:;
Alih-alih mengambil value_type
itu membutuhkan daftar argumen variadik, sehingga itu berarti bahwa Anda sekarang dapat dengan sempurna meneruskan argumen dan membangun langsung objek ke wadah tanpa sementara sama sekali.
Itu berguna karena tidak peduli seberapa banyak kepintaran RVO dan memindahkan semantik ke meja, masih ada kasus rumit di mana push_back cenderung membuat salinan yang tidak perlu (atau memindahkan). Misalnya, dengan insert()
fungsi tradisional a std::map
, Anda harus membuat sementara, yang kemudian akan disalin ke std::pair<Key, Value>
, yang kemudian akan disalin ke peta:
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);
Jadi mengapa mereka tidak mengimplementasikan versi emplace_back yang tepat di MSVC? Sebenarnya, itu menyadap saya beberapa waktu yang lalu, jadi saya mengajukan pertanyaan yang sama di blog Visual C ++ . Berikut adalah jawaban dari Stephan T Lavavej, pengelola resmi implementasi perpustakaan standar Visual C ++ di Microsoft.
T: Apakah fungsi beta 2 emplace hanya semacam placeholder sekarang?
A: Seperti yang Anda ketahui, template variadic tidak diimplementasikan dalam VC10. Kami mensimulasikan mereka dengan mesin preprocessor untuk hal-hal seperti
make_shared<T>()
, tuple, dan hal-hal baru di <functional>
. Mesin preprosesor ini relatif sulit digunakan dan dirawat. Selain itu, ini secara signifikan memengaruhi kecepatan kompilasi, karena kami harus berulang kali menyertakan subpos. Karena kombinasi dari batasan waktu dan masalah kecepatan kompilasi kami, kami belum mensimulasikan templat variadic di fungsi emplace kami.
Ketika templat variadic diimplementasikan dalam kompiler, Anda dapat berharap bahwa kami akan memanfaatkannya di perpustakaan, termasuk di fungsi emplace kami. Kami menanggapi kesesuaian dengan sangat serius, tetapi sayangnya, kami tidak dapat melakukan semuanya sekaligus.
Itu keputusan yang bisa dimengerti. Setiap orang yang mencoba sekali saja untuk meniru template variadic dengan trik mengerikan preprocessor tahu betapa menjijikkannya hal ini.