В дополнение к тому, что посетитель сказал:
Функция, void emplace_back(Type&& _Val)
предоставляемая MSCV10, не соответствует и избыточна, потому что, как вы заметили, она строго эквивалентна push_back(Type&& _Val)
.
Но настоящая форма C ++ 0x emplace_back
действительно полезна void emplace_back(Args&&...)
:;
Вместо того, чтобы брать a, value_type
он принимает список аргументов с переменным числом аргументов, что означает, что теперь вы можете безошибочно пересылать аргументы и непосредственно создавать объект в контейнере без какого-либо временного объекта.
Это полезно, потому что независимо от того, насколько умные RVO и семантика перемещения приносят в таблицу, все еще существуют сложные случаи, когда push_back может создавать ненужные копии (или перемещаться). Например, с помощью традиционной insert()
функции a std::map
вы должны создать временный объект, который затем будет скопирован в a std::pair<Key, Value>
, который затем будет скопирован на карту:
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);
Так почему же они не реализовали правильную версию emplace_back в MSVC? На самом деле, это слишком долго меня беспокоило, поэтому я задал тот же вопрос в блоге по Visual C ++ . Вот ответ Стефана Т Лававея, официального сопровождающего реализации стандартной библиотеки Visual C ++ в Microsoft.
Вопрос: Являются ли бета 2 emplace функции просто своего рода заполнителем прямо сейчас?
A: Как вы, возможно, знаете, шаблоны Variad не реализованы в VC10. Мы моделируем их с помощью препроцессорного оборудования для таких вещей, как
make_shared<T>()
кортеж и новые вещи <functional>
. Это препроцессорное оборудование относительно сложно в использовании и обслуживании. Кроме того, это существенно влияет на скорость компиляции, так как нам приходится многократно включать подзаголовки. Из-за сочетания наших временных ограничений и проблем со скоростью компиляции мы не смоделировали шаблоны переменных в наших функциях emplace.
Когда в компиляторе реализованы различные шаблоны, можно ожидать, что мы воспользуемся ими в библиотеках, в том числе в наших функциях emplace. Мы очень серьезно относимся к соответствию, но, к сожалению, мы не можем сделать все сразу.
Это понятное решение. Каждый, кто хотя бы один раз пытался эмулировать шаблон вариации с ужасными приемами препроцессора, знает, как отвратительно получается это.