[c++] push_back vs emplace_back



2 Answers

emplace_back не должен принимать аргумент типа vector::value_type , а вместо него - переменные аргументы, которые перенаправляются конструктору добавленного элемента.

template <class... Args> void emplace_back(Args&&... args); 

Можно передать value_type который будет перенаправлен на конструктор копирования.

Поскольку он пересылает аргументы, это означает, что если у вас нет значения rvalue, это все равно означает, что контейнер будет хранить «скопированную» копию, а не перемещенную копию.

 std::vector<std::string> vec;
 vec.emplace_back(std::string("Hello")); // moves
 std::string s;
 vec.emplace_back(s); //copies

Но вышеуказанное должно быть идентично тому, что делает push_back . Вероятно, это скорее предназначено для использования таких случаев, как:

 std::vector<std::pair<std::string, std::string> > vec;
 vec.emplace_back(std::string("Hello"), std::string("world")); 
 // should end up invoking this constructor:
 //template<class U, class V> pair(U&& x, V&& y);
 //without making any copies of the strings
Question

Я немного смущен относительно разницы между push_back и emplace_back .

void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);

Так как есть перегрузка push_back с использованием ссылки rvalue, я не совсем понимаю, какова цель emplace_back ?







Соответствующая реализация emplace_back будет перенаправлять аргументы в vector<Object>::value_type при добавлении в вектор. Я помню, что Visual Studio не поддерживала вариационные шаблоны, но с вариационными шаблонами будет поддерживаться в Visual Studio 2013 RC, поэтому я предполагаю, что будет добавлена ​​соответствующая подпись.

С emplace_back , если вы пересылаете аргументы непосредственно в конструктор vector<Object>::value_type , вам не нужен тип, который может быть подвижным или скопированным для функции emplace_back , строго говоря. В случае с vector<NonCopyableNonMovableObject> это не полезно, так как для vector<Object>::value_type требуется скопировать или перемещать тип для роста.

Но учтите, что это может быть полезно для std::map<Key, NonCopyableNonMovableObject> , поскольку, как только вы выделяете запись на карте, ее больше не нужно перемещать или копировать, в отличие от vector , что означает, что вы можете использовать std::map эффективно с отображенным типом, который не является ни копируемым, ни подвижным.




Related