C++17 中 std::map 和 std::unordered_map

举报
码事漫谈 发表于 2025/02/16 10:59:34 2025/02/16
【摘要】 C++17 中 std::map 和 std::unordered_map 的 try_emplace 与 insert_or_assign 方法详解 1. try_emplace 方法 1.1 功能描述 1.2 返回值说明 1.3 优势体现 1.4 示例代码 2. insert_or_assign 方法 2.1 功能描述 2.2 返回值说明 2.3 示例代码 3. 总结 C++17 中 ...

C++17 中 std::map 和 std::unordered_map 的 try_emplace 与 insert_or_assign 方法详解

在 C++17 标准库中,std::mapstd::unordered_map 容器引入了 try_emplaceinsert_or_assign 这两个实用的成员函数。这两个方法为开发者在处理键值对的插入和更新操作时,提供了更为高效和灵活的选择,极大地提升了代码的性能和可维护性。下面将对这两个方法进行详细的介绍和分析。

1. try_emplace 方法

try_emplace 是 C++17 新引入的成员函数,主要用于在 std::mapstd::unordered_map 中插入新的元素。它与 emplace 方法存在一定的区别,try_emplace 不会移动右值参数,即便最终插入操作未能成功执行。

1.1 功能描述

try_emplace 的核心功能是:当指定的键在容器中不存在时,它会使用传入的参数构造相应的值,并将键值对插入到容器中;而当指定的键已经存在于容器中时,try_emplace 不会执行任何操作,容器的状态保持不变。

1.2 返回值说明

该方法的返回值是一个 std::pair<iterator, bool> 类型的对象。其中,iterator 指向容器中与指定键对应的键值对(无论插入操作是否成功);bool 值则表示本次插入操作是否成功,true 代表插入成功,false 代表插入失败(即键已存在)。

1.3 优势体现

对于那些对移动语义敏感的值类型,比如 std::unique_ptr 等智能指针类型,try_emplace 方法提供了更高的安全性。因为它不会在键已存在时错误地移动右值参数,从而避免了潜在的资源管理问题和未定义行为。

1.4 示例代码

#include <iostream>
#include <unordered_map>
#include <string>

int main() {
    std::unordered_map<std::string, std::string> myMap;

    // 尝试插入键值对 "key1": "value1"
    auto result = myMap.try_emplace("key1", "value1");
    std::cout << "Key1 inserted: " << (result.second? "true" : "false") << std::endl;

    // 再次尝试插入键值对 "key1": "new_value",由于键已存在,插入失败
    result = myMap.try_emplace("key1", "new_value");
    std::cout << "Key1 inserted again: " << (result.second? "true" : "false") << std::endl;

    // 遍历输出容器中的所有键值对
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

2. insert_or_assign 方法

insert_or_assign 同样是 C++17 引入的成员函数,它主要用于在 std::mapstd::unordered_map 中插入或更新键值对。

2.1 功能描述

insert_or_assign 的功能是:当指定的键在容器中不存在时,它会插入一个新的键值对;而当指定的键已经存在于容器中时,它会使用传入的新值来更新该键对应的旧值。

2.2 返回值说明

该方法的返回值是一个 iterator 类型的对象,它指向容器中插入或更新后的键值对。

2.3 示例代码

#include <iostream>
#include <unordered_map>
#include <string>

int main() {
    std::unordered_map<std::string, std::string> myMap;

    // 插入键值对 "key1": "value1"
    auto it = myMap.insert_or_assign("key1", "value1");
    std::cout << "Key1 inserted/updated: " << it->second << std::endl;

    // 更新键值对 "key1" 的值为 "new_value"
    it = myMap.insert_or_assign("key1", "new_value");
    std::cout << "Key1 inserted/updated again: " << it->second << std::endl;

    // 遍历输出容器中的所有键值对
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

3. 总结

  • try_emplace:适用于在插入操作时,需要避免不必要的移动操作的场景,特别是对于那些对移动语义敏感的类型,使用 try_emplace 可以确保代码的安全性和正确性。
  • insert_or_assign:适用于既需要插入新的键值对,又需要在键已存在时更新其值的场景。该方法提供了一种简洁的方式来处理这两种常见的操作需求。

如果开发者需要了解更详细的使用场景和性能分析,可以参考 C++ 标准库的官方文档,以获取更全面和准确的信息。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。