【发布时间】:2012-12-07 22:54:39
【问题描述】:
我会先问这个问题,然后是动机,最后是一个按预期编译和执行的说明性代码示例。
问题
如果我可以保证迭代器在我需要使用它的持续时间内不会失效,那么持有指向迭代器的指针是否安全(例如指向list<int>::iterator 的指针)。
动机
我有多个容器,我需要将一个容器中的项目直接交叉引用到另一个容器中的相应项目,依此类推。一个容器中的项目可能并不总是在另一个容器中具有相应的项目。
因此,我的想法是将一个指向迭代器的指针存储在容器#1 中存储的元素中,以此类推。为什么?因为一旦有了迭代器,我不仅可以访问容器 #2 中的元素,而且如果需要,我还可以擦除容器 #2 中的元素等。
如果容器#2 中有对应的元素,我会在容器#1 的元素中存储一个指向迭代器的指针。否则,此指针将设置为 NULL。现在我可以快速检查指向迭代器的指针是否为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);
}
【问题讨论】:
-
为什么不直接保存迭代器,
end迭代器的意思是NULL -
另外还有 Boost.Optional,这是一种通用的方式来表示“要么是一个值,要么是一个没有值的特殊情况”。因为一切都在一个地方处理,所以您不必考虑指针的引用的生命周期。
-
保存指针(我希望)给了我两件事:1. 重量轻 2. 无需担心 end() 本身会失效。现在我承认我不确定这些担忧是否有效。
-
感谢@SteveJessop,今天学到了一些新东西。我用
optional<MyIterator>尝试了 Boost Optional,它工作正常。