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

C++17 中 std::map 和 std::unordered_map 的 try_emplace 与 insert_or_assign 方法详解
在 C++17 标准库中,std::map 和 std::unordered_map 容器引入了 try_emplace 和 insert_or_assign 这两个实用的成员函数。这两个方法为开发者在处理键值对的插入和更新操作时,提供了更为高效和灵活的选择,极大地提升了代码的性能和可维护性。下面将对这两个方法进行详细的介绍和分析。
1. try_emplace 方法
try_emplace 是 C++17 新引入的成员函数,主要用于在 std::map 或 std::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::map 或 std::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++ 标准库的官方文档,以获取更全面和准确的信息。
- 点赞
- 收藏
- 关注作者
评论(0)