unordered_multimap 在 C++ STL 中的 emplace() 函数
C++ STL 中的 unordered_multimap
是一个关联容器,它允许存储具有相同键的多个元素。它的插入操作与 unordered_map
相同,都有 emplace()
函数。本文将详细介绍 unordered_multimap
的 emplace()
函数。
什么是 emplace() 函数?
在使用 map
和 unordered_map
这类关联容器的时候,我们常常需要通过一个键值 key
去插入一个元素,然后再修改这个元素的值。这两步操作虽然简单,但是需要执行两次查找,性能较低。
为了解决这个问题,C++11 引入了 emplace()
函数。emplace()
函数在插入元素的同时,直接在元素的位置上构造一个对象,避免了两次查找的问题,能够提高程序的效率。
unordered_multimap 的 emplace() 函数
unordered_multimap
的 emplace()
函数与 unordered_map
相同,其函数原型如下:
“` c++
template< class... Args >
iterator emplace( Args&&… args );
可以看出,`emplace()` 函数可以接受任意数量的参数。这些参数将被用来构造一个新的元素插入到 `unordered_multimap` 中。下面是一个简单的例子,展示了如何使用 `emplace()` 函数向 `unordered_multimap` 中插入元素:
``` c++
#include <iostream>
#include <unordered_map>
int main()
{
std::unordered_multimap<char, int> mymap;
// 使用 emplace() 函数插入元素
mymap.emplace('a', 1);
mymap.emplace('b', 2);
mymap.emplace('c', 3);
// 遍历 unordered_multimap
for (auto& x : mymap) {
std::cout << x.first << ": " << x.second << std::endl;
}
return 0;
}
</code></pre>
上面的代码中,我们使用 <code>emplace()</code> 函数向 <code>unordered_multimap</code> 中插入了 3 个元素。然后,我们遍历 <code>unordered_multimap</code>,输出每个元素的键和值。
输出结果如下:
<pre><code class="language-bash line-numbers">a: 1
b: 2
c: 3
</code></pre>
可以看出,元素插入成功,并且顺序与插入顺序相同。
<h2>使用 emplace() 插入自定义类型的对象</h2>
我们也可以通过 <code>emplace()</code> 函数向 <code>unordered_multimap</code> 中插入自定义类型的对象,下面是一个具体的例子:
``` c++
#include
#include
#include
class Person
{
public:
std::string name;
int age;
Person(std::string name, int age)
{
this->name = name;
this->age = age;
}
bool operator==(const Person& other) const
{
return (this->name == other.name) && (this->age == other.age);
}
};
namespace std
{
template <>
struct hash
{
size_t operator()(const Person& person) const
{
return hash()(person.name) ^ hash()(person.age);
}
};
}
int main()
{
std::unordered_multimap<Person, int> mymap;
// 使用 emplace() 函数插入元素
mymap.emplace(Person("Alice", 18), 80);
mymap.emplace(Person("Bob", 20), 90);
mymap.emplace(Person("Charlie", 22), 95);
// 遍历 unordered_multimap
for (auto& x : mymap) {
std::cout << "Name: " << x.first.name << ", Age: " << x.first.age << ", Score: " << x.second << std::endl;
}
return 0;
}
上面的代码中,我们定义了一个 `Person` 类型,包含姓名和年龄两个成员变量。然后我们重载了 `<hash>` 函数,实现对 `Person` 类型对象的哈希值计算。最后,我们使用 `emplace()` 函数向 `unordered_multimap` 中插入了 3 个元素,每个元素都是一个 `Person` 类型对象和一个 `int` 类型值。然后,我们遍历 `unordered_multimap`,输出每个元素的 `Person` 对象的姓名、年龄和 `int` 类型值。
输出结果如下:
```bash
Name: Alice, Age: 18, Score: 80
Name: Bob, Age: 20, Score: 90
Name: Charlie, Age: 22, Score: 95
可以看出,自定义类型的对象也能够成功插入到 unordered_multimap
中。
emplace() 存在的问题
emplace()
函数虽然可以避免多次查找的问题,提高了程序的效率,但是在一些情况下会存在问题。
首先,由于 emplace()
函数可以接受任意数量的参数,如果我们在使用 emplace()
函数的时候没有正确地传递参数,或者传递了多余的参数,会导致编译错误或者运行时错误。
其次,如果我们希望使用 emplace()
函数向 unordered_multimap
中插入一个键值已经存在的元素,由于 emplace()
函数不能直接访问 unordered_multimap
中的元素,我们只能通过 find()
函数或者 equal_range()
函数来查找到这个元素的位置,然后使用 emplace_hint()
函数在这个位置上构造新的元素。
emplace() 和 insert() 函数的区别
除了 emplace()
函数之外,unordered_multimap
还提供了 insert()
函数来支持插入元素。二者的区别如下:
emplace()
函数会在插入元素的同时直接在元素的位置上构造一个对象,insert()
函数会在插入元素之后再次构造对象。
emplace()
函数可以接受任意数量的参数,insert()
函数则需要接受一个元素类型的值或引用。
通常来说,在使用 unordered_multimap
插入元素的时候,尽量使用 emplace()
函数,以提高程序的效率。
结论
emplace()
函数是 unordered_multimap
中的一个重要函数,它可以用来向 unordered_multimap
中插入元素,同时避免了多次查找的问题,提高了程序的效率。在使用 emplace()
函数的时候,需要注意参数的正确传递。如果希望插入一个键值已经存在的元素,可以通过 find()
函数或者 equal_range()
函数查找到位置,再使用 emplace_hint()
函数插入元素。在插入元素的时候,应该尽量使用 emplace()
函数,以提高程序的效率。