问题描述
在C ++中unordered_map :: emplace和unordered_map :: insert之间有什么区别?
What is the difference between unordered_map :: emplace and unordered_map :: insert in C++ ?
推荐答案
unordered_map :: insert
复制或将键值对移动到容器中。 :
unordered_map::insert
copies or moves a key-value pair into the container. It is overloaded to accept reference-to-const or an rvalue reference:
std::pair<iterator,bool> insert(const std::pair<const Key, T>& value);
template<class P>
std::pair<iterator,bool> insert(P&& value);
unordered_map :: emplace
不必要的副本或移动通过构造元素到位。它使用完美的转发和可变参数模板来:
unordered_map::emplace
allows you to avoid unnecessary copies or moves by constructing the element in place. It uses perfect forwarding and a variadic template to forward arguments to the constructor of the key-value pair:
template<class... Args>
std::pair<iterator,bool> emplace(Args&&... args);
但是这两个函数之间有很多重叠。 emplace
可用于转发到键/值对的复制/移动构造函数,允许使用 insert
would。这意味着使用 emplace
不保证您将避免复制或移动。同样,接受rvalue-reference的 insert
的版本实际上是模板化的,并且接受任何类型 P
值对可以从 P
构造。
But there is a great deal of overlap between the two functions. emplace
can be used to forward to the copy/move constructor of the key-value pair which allows it to be used just as insert
would. This means that use of emplace
doesn't guarantee you will avoid copies or moves. Also the version of insert
that takes an rvalue-reference is actually templated and accepts any type P
such that the key-value pair is constructible from P
.
编辑:Howard Hinnant运行显示有时插入
比 emplace
更快
如果你确实想复制/移动到容器中,使用 insert
可能是明智的,因为你更可能得到一个编译错误if你传递不正确的参数。
If you definitely do want to copy/move into the container it might be wise to use insert
because you are more likely to get a compilation error if you pass incorrect arguments. You need to be more careful you are passing the correct arguments to the emplacement functions.
小例子:
#include <unordered_map>
#include <iostream>
int main() {
auto employee1 = std::pair<int, std::string>{1, "John Smith"};
auto employees = std::unordered_map<int, std::string>{};
employees.insert(employee1); // copy insertion
employees.insert(std::make_pair(2, "Mary Jones")); // move insertion
employees.emplace(3, "James Brown"); // construct in-place
for (const auto& employee : employees)
std::cout << employee.first << ": " << employee.second << "\n";
}
Edit2:也可以使用带有多个构造函数参数的键或值的 unordered_map :: emplace
。使用 std :: pair
,您仍然可以避免不必要的副本或移动。
On request. It is also possible to use unordered_map::emplace
with a key or value that takes more than one constructor parameter. Using the std::pair
piecewise constructor you can still avoid unnecessary copies or moves.
#include <unordered_map>
#include <iostream>
struct Employee {
std::string firstname;
std::string lastname;
Employee(const std::string& firstname, const std::string& lastname)
: firstname(firstname), lastname(lastname){}
};
int main() {
auto employees = std::unordered_map<int, Employee>{};
auto employee1 = std::pair<int, Employee>{1, Employee{"John", "Smith"}};
employees.insert(employee1); // copy insertion
employees.insert(std::make_pair(2, Employee{"Mary", "Jones"})); // move insertion
employees.emplace(3, Employee("Sam", "Thomas")); // emplace with pre-constructed Employee
employees.emplace(std::piecewise_construct,
std::forward_as_tuple(4),
std::forward_as_tuple("James", "Brown")); // construct in-place
}
这篇关于在C ++中unordered_map :: emplace和unordered_map :: insert之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!