C++:从值类型指针强制转换为包含迭代器
C++: cast from value type pointer to containing iterator
std::unordered_map<K,T>
提供了类似find
的方法,这些方法返回std::unordered_map<K,T>::iterator
。据我所知,迭代器仍然有效,除非发生重新散列。
但我的怀疑是,没有保证::iterator
->T *
->::iterator
的往返方式,类似于Linux链表中的"破解"。我认为这是因为迭代器只需要通过->second
来取消引用,但我看不出在容器中需要持久存储类型。
那么,我说得对吗?我是否需要保留迭代器,或者T *ptr = &myiterator->second
稍后是否可以返回到->second
成员地址为ptr
的迭代器指针?
这个问题自然也适用于其他容器的迭代器。
第一个问题很简单:通常,没有直接的方法可以从指向元素或值的指针中获取迭代器。也就是说,要从值中获取迭代器,通常需要搜索容器。由于std::vector<T>
需要是连续的,您可以使用简单的计算(这需要v
是非空的)从指针中获得迭代器:
std::vector<T> v(...);
T* ptr = ...;
std::vector<T>::iterator it(v.begin() + (ptr - &v[0]));
跟踪迭代器和值是否保持稳定并非易事,因为相关的保证分布在多个子句上,例如:
23.2.1【集装箱要求概述】第11段:
除非另有规定(明确地或通过根据其他函数定义函数),否则调用容器成员函数或将容器作为参数传递给库函数不会使该容器中对象的迭代器无效或更改该对象的值。
23.2.4[相关要求]第9段:
插入和模板成员不应影响迭代器和对容器的引用的有效性,擦除成员应仅使迭代器或对已擦除元素的引用无效。
23.2.5[要求]第9段:
Rehashing会使迭代器失效,更改元素之间的顺序,以及更改元素出现在哪个bucket中,但不会使指向元素的指针或引用失效。。。
23.2.5[要求]第14段:
insert和template成员不应影响对容器元素的引用的有效性,但可能会使容器的所有迭代器无效。。。
23.2.5[要求]第15段:
如果(N+N)<z*B,其中N是插入操作之前容器中元素的数量,N是插入的元素数量,B是容器的桶数,z是容器的最大负载因子。
以上子句应该是关于关联容器的迭代器有效性的重要子句。无序关联容器中的迭代器有效性完全取决于容器是否被重新散列。看来重洗是可以控制的,以避免意外发生。
然而,无序容器的整体思想是,使用find()
定位对象是非常有效的。应该永远不需要将迭代器存储到元素中,因为您可以找到它们。当然,如果你有一个std::unordered_multimap<K, V>
或std::unordered_multiset<V>
,你可能需要知道你在看哪个等效元素
关联容器(set
、multi_set
、map
、multi_map
及其unordered_
同类)在向容器添加元素时不会使指针或引用失效;它们可以使迭代器无效。此外,删除元素时,只有迭代器、指针和对这些元素的引用无效。这样做的一个后果是,如果您获取一个元素的地址,那么只要该元素保留在容器中,该地址就会保持有效。
没有可移植的方法可以直接从元素的地址转换为指向该元素的迭代器。如果你需要这样做,你必须搜索元素。
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 在混合代码库中将C转换为C++时出现许多包含错误
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 如何将包含指数的 QString 转换为C++中的双倍?
- 无法将字符数组转换为包含 utf-8 字符的字符串
- 转换包含向量 C++ 的语法和结构
- 将包含多个元素的字符串作为输入并转换为矢量 C++
- 如何为代码包含负值?号码系统转换
- C++将包含非人类可读数据的字符串转换为 200 双精度
- 包含可变参数包的第一个可转换类型的别名的结构
- C++要包含在词法强制转换中的头文件
- 无法转换 .CATPart 文件.错误:输入文件路径似乎包含不支持的字符
- 如果必须包含西里尔字符,如何将 char* 转换为 std::string?
- 如何将包含中文或韩语的字符串转换为十六进制/字节
- 如何将智能指针向量转换为常量向量,该常量向量包含指向常量的智能指针
- 如何在将秒转换为分钟且余数小于 10 秒时包含前导零
- 如何在C++中将边列表转换为邻接矩阵,其中包含连接到顶点的边数而不是一条边?
- 如何将包含 '