我有一个DataIterator
按需生成值的迭代器,因此取消引用运算符返回一个Data,而不是Data&.我认为这是一件好事,直到我试图通过将数据包装在reverse_iterator中来反转数据DataIterator.
DataCollection collection std::reverse_iteratorrBegin(iter) //iter is a DataIterator that's part-way through the collection std::reverse_iterator rEnd(collection.cbegin()); auto Found = std::find_if( rBegin, rEnd, [](const Data& candidate){ return candidate.Value() == 0x00; });
当我运行上面的代码时,它永远不会找到一个值等于0的Data对象,即使我知道一个存在.当我在谓词中插入一个断点时,我会看到奇怪的值,我永远不会期望看到像0xCCCC - 可能是未初始化的内存.会发生什么是reverse_iterator的解引用运算符看起来像这样(来自xutility - Visual Studio 2010)
Data& operator*() const { // return designated value DataIterator _Tmp = current; return (*--_Tmp); //Here's the problem - the * operator on DataIterator returns a value instead of a reference }
最后一行是问题所在 - 创建临时数据并返回对该数据的引用.该引用立即无效.
如果我将std :: find_if中的谓词更改为(数据候选者)而不是(const数据和候选者),那么谓词就可以了 - 但我很确定我只是幸运地遇到了未定义的行为.引用无效,但我在内存被破坏之前复制数据.
我能做什么?
修复我的DataIterator,以便operator*返回Data而不是Data?我真的不明白这是怎么回事.我的DataIterator返回Data而不是Data的重点是因为我没有空间将整个未压缩的数据集保存在内存中,所以我创建了你想要按需查看的项目. 也许我可以抓住'当前'数据值 - 但是当你递增或递减DataIterator时,该引用将变为无效. 编辑 其中一个答案建议使用shared_ptr
编写reverse_iterator的特化并使其解引用运算符返回值而不是引用?这似乎是令人沮丧的工作量,但可以理解,因为这是我的DataIterator在这里不好玩 - 而不是STL的其余部分.
沿着同样的路线,也许使一个反向的find_if - 可能比专门化reverse_iterator更少的工作.
我还没有想到的其他东西
我可以对DataIterator做些什么来阻止其他人在6个月后尝试同样的事情时,花半天时间弄清楚出了什么问题?