在C 中将指针固定为迭代器是否安全
Is it safe to hold pointers to iterators in C++?
我将首先提出问题,然后将动机和动机提出,最后是汇编和执行预期的说明性代码样本。
问题
如果我可以向自己保证,迭代器在我需要使用时不会在持续时间内无效,那么将指针固定到迭代器的指针是安全的(例如,指向list<int>::iterator
的指针)。
动机
我有多个容器,我需要从一个容器中存放在一个容器中的物品中的直接交叉引用到另一个容器中的相应项目等。一个容器中的一个项目可能并不总是在另一个容器中具有相应的项目。
因此,我的想法是在存储在容器#1中的元素中等元素中,将迭代器的指针存储到元素中。为什么?因为一旦有一个迭代器,我不仅可以在容器#2中访问元素,而且可以在需要时,我还可以在容器#2等中删除元素。
。如果容器#2中有一个相应的元素,我将在容器#1中存储一个指向迭代器的指针。否则,该指针将设置为空。现在,我可以快速检查一下,如果指向迭代器的指针为null,则在容器#2中没有相应的元素,如果非null,我可以继续访问它。
那么,以这种方式将指针存储到迭代器上是安全的吗?
代码样本
#include <iostream>
#include <list>
using namespace std;
typedef list<int> MyContainer;
typedef MyContainer::iterator MyIterator;
typdef MyIterator * PMyIterator;
void useIter(PMyIterator pIter)
{
if (pIter == NULL)
{
cout << "NULL" << endl;
}
else
{
cout << "Value: " << *(*pIter) << endl;
}
}
int main()
{
MyContainer myList;
myList.push_back(1);
myList.push_back(2);
PMyIterator pIter = NULL;
// Verify for NULL
useIter(pIter);
// Get an iterator
MyIterator it = myList.begin();
// Get a pointer to the iterator
pIter = & it;
// Use the pointer
useIter (pIter);
}
迭代器通常按值处理。例如,begin()
和end()
将返回类型iterator
的实例(对于给定的迭代器类型),而不是iterator&
,因此它们每次都返回值的 copies 。
您当然可以获取此副本的地址,但是您不能指望对begin()
或end()
的新调用将返回具有相同地址的对象,并且只要您握住迭代器对象,地址才有效你自己。
std::vector<int> x { 1, 2, 3 };
// This is fine:
auto it = x.begin();
auto* pi = ⁢
// This is not (dangling pointer):
auto* pi2 = &x.begin();
保持迭代剂的指针很少有意义:迭代器已经是轻量级处理数据。进一步的间接通常是设计不良的迹象。在您的示例中,指针没有意义。只需通过普通迭代器即可。
迭代器的问题在于,容器上有很多操作使它们无效(这取决于所讨论的容器)。当您将迭代器固定到属于另一个类的容器时,您永远不会知道何时发生这种操作,并且没有简单的方法可以发现迭代器现在无效。
此外,直接删除属于另一个类的容器中的元素是违反封装原理的行为。当您想删除其他类的数据时,应该最好调用该类的公共方法,然后删除数据。
是的,只要您可以确保迭代器不会无效并且不会脱离范围。
听起来可怕。迭代器是一个对象,如果它离开范围,则指针无效。如果您在容器#2中删除一个对象,则所有迭代器都可能无效(取决于容器),因此您的指针变得毫无用处。
为什么不存储迭代器本身?对于1个没有指任何内容的容器中的元素,请存储container2.end()。只要迭代器没有无效,这就是可以的。如果是,您需要重新生成映射。
是的,可以像其他类型一样在迭代器上处理指针,但在您的示例中,这不是必需的,因为您可以简单地将原始迭代器作为参考传递。
通常,存储迭代器并不是一个好主意,因为在修改容器时,迭代器可能会变得无效。最好将容器存储并在需要时创建迭代器。
- std::vector::迭代器是否可以合法地作为指针
- 钳制迭代器是否有效
- 测试迭代器是否位于列表中的最后一个
- 迭代器是否分配内存(如指针)?
- 在擦除或修改作为不同索引键的值时,boost::multi_index 迭代器是否无效?
- 输入迭代器是否可以仅在赋值的右侧符号上取消引用?
- 由迭代器构造的反向迭代器是否是其以前的迭代器?
- 检查迭代器是否具有我们要在C++中分配的值是否明智的优化
- 是否可以确定传递的迭代器是否属于关联的 std 容器?
- 来自并发哈希映射的迭代器是否安全
- std::迭代器是否可以检查该迭代器上是否存在下一个元素?(此设计受到家庭作业的限制)
- 检查反向迭代器是否已越过正向迭代器
- 如何检查迭代器是否是C 中的output_iterator
- 在C 中将指针固定为迭代器是否安全
- 指向同一项的两个映射迭代器是否保证相等
- 如何找出迭代器是否位于某个范围内
- 标准库容器迭代器的递增/递减迭代器是否具有确定性
- 迭代器是否以相同的顺序迭代 boost::unordered_set 或 boost::unordered_map 只要集合不变?
- 如何检查迭代器是否形成连续的内存区域
- 递增可变输入迭代器是否会使旧迭代器值失效