C++中节点句柄持有元素时,映射值的引用是否可用?
C++ 节点句柄持有元素时,原映射值的引用是否可用?
是的,当元素被节点句柄(node handle)接管后,原映射值的引用(比如代码中的ref_mapped)同样不可用,访问这类引用属于未定义行为。
具体分析
当调用unordered_map::extract后,目标键值对会脱离原容器,完全由节点句柄nh持有。此时:
- 原迭代器
iter直接失效,无法再进行任何合法操作。 ref_ele是对原元素(value_type类型)的引用,元素已不在容器内,该引用变为悬空引用,不可用。ref_mapped是对原元素的second成员(即映射值)的引用,本质上还是指向已脱离容器的元素的一部分,同样成为悬空引用,绝对不能再访问,否则会触发未定义行为(比如程序崩溃、数据损坏等)。
如果需要操作被节点句柄持有的元素,应该通过节点句柄自身的接口:
- 用
nh.value()获取完整的键值对引用 - 用
nh.key()获取键的引用 - 用
nh.mapped()获取映射值的引用
这些引用在节点句柄的生命周期内都是有效的,直到元素被插入到其他容器或节点句柄被销毁。
代码对应说明
#include <string> #include <unordered_map> int main() { std::unordered_map<int, std::string> map{{1, "one"}, {2, "two"}, {3, "three"}}; auto iter = map.find(1); // (1) 提取前有效 auto& ref_ele = *iter; // (2) 提取前有效 auto& ref_mapped = iter->second; // (3) 提取前有效 auto nh = map.extract(1); // (1): 迭代器失效,不可用 // (2): 悬空引用,不可用 // (3): 悬空引用,不可用 // 合法操作示例:通过节点句柄访问 // std::cout << nh.mapped() << std::endl; // 输出 "one" return 0; }
内容的提问来源于stack exchange,提问作者tearfur
相关产品推荐
相关产品推荐

