В дополнение к тому, что посетитель сказал:
Функция void emplace_back(Type&& _Val)
, предоставляемая MSCV10, не соответствует и избыточна, потому что, как вы заметили, она строго эквивалентна push_back(Type&& _Val)
.
Нореальная форма C ++ 0x emplace_back
действительно полезна: void emplace_back(Args&&...)
;
Вместо того, чтобы принимать value_type
, требуется список аргументов с переменным числом аргументов, что означает, чтоТеперь вы можете полностью пересылать аргументы и напрямую создавать объект в контейнере без какого-либо временного объекта.
Это полезно, потому что независимо от того, насколько умный RVO и перемещение семантики привносят в таблицу, все еще есть сложные случаи, когда push_back может создавать ненужные копии (или перемещаться).Например, с традиционной insert()
функцией std::map
вам необходимо создать временный объект, который затем будет скопирован в 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.Мы очень серьезно относимся к соответствию, но, к сожалению, мы не можем сделать все сразу.
Это понятное решение.Каждый, кто хотя бы один раз пытался эмулировать шаблон вариации с ужасными приемами препроцессора, знает, как отвратительно получается это.