unordered_multimap 在 C++ STL 中的 emplace() 函数

unordered_multimap 在 C++ STL 中的 emplace() 函数

C++ STL 中的 unordered_multimap 是一个关联容器,它允许存储具有相同键的多个元素。它的插入操作与 unordered_map 相同,都有 emplace() 函数。本文将详细介绍 unordered_multimapemplace() 函数。

什么是 emplace() 函数?

在使用 mapunordered_map 这类关联容器的时候,我们常常需要通过一个键值 key 去插入一个元素,然后再修改这个元素的值。这两步操作虽然简单,但是需要执行两次查找,性能较低。

为了解决这个问题,C++11 引入了 emplace() 函数。emplace() 函数在插入元素的同时,直接在元素的位置上构造一个对象,避免了两次查找的问题,能够提高程序的效率。

unordered_multimap 的 emplace() 函数

unordered_multimapemplace() 函数与 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() 函数,以提高程序的效率。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

C++ 教程