定义自定义(STL兼容)迭代器,其中值类型不是CopyConstuctible或Assignable

时间:2011-05-04 11:58:50

标签: c++ windows boost stl iterator

我希望定义一个使用无法复制的值类型的自定义迭代器。

这个的基本原理是迭代器将负责Windows下的模块枚举,并且我使用CreateToolhelp32Snapshot / Module32First / Module32Next API来避免必须预处理整个模块列表(例如,每个迭代器增量应该前进到按需列表中的下一个模块,以避免不必要的开销。)这样的问题是这些API需要使用由Toolhelp API管理的“HANDLE”,因此除了通过调用First / Next之外,我无法控制列表中的“position”。

技术上我可以复制句柄,但是你会遇到这样的问题:

auto Iter1 = ModList.begin(); // Assume 'ModList' is an instance of my class which manages construction etc of my iterator
auto Iter2 = Iter1; // Both iterators now point to the first module in the list
++Iter1; // BOTH iterators now point to the second module in this list!! We just 'broke' the expected behavior of 'Iter2'.

是否可以定义一个与STL兼容的迭代器(可以使用标准算法等),它与一个无法复制或分配的值类型一起使用?

我还可以将值类型包装在迭代器实现中的共享指针中,这样可以使迭代器本身可以复制和分配,但它仍然无法解决上面代码中列出的问题。

注意:如果有帮助,我可以使值类型可移动。

我的代码库中已经有很大的Boost依赖,所以请随意提出使用Boost的解决方案。

对于写得不好的问题感到抱歉,我已经有一段时间了,我的大脑不再需要正常工作了。 :P如果需要澄清,请告诉我。

2 个答案:

答案 0 :(得分:2)

如果将迭代器标记为InputIterator而不是ForwardIterator,那么您描述的行为是意外的。增加InputIterator会使其副本无效,因此在它之后它们看起来并不重要。

您可以将它与接受InputIterator的标准算法一起使用,这正是那些可以合理地实现为单通道算法而不是多通道算法的算法。

根据您的算法实现是否检查迭代器标记,您可能无法获得任何帮助以确保您不会错误地使用它。 InputIterator和ForwardIterator接口的“签名”没有区别,仅在语义上,所以单独编译时鸭子打字没有帮助。

答案 1 :(得分:1)

迭代器应该在逻辑上引用元素 - 它不应该元素。您将需要一个模块的后端集合,以及引用此集合中各个元素的迭代器 - 就像stdlib迭代器一样。递增迭代器应该改变它引用的实际元素,而不修改后端集合。

对于您的特定问题,您可以创建一个按需继续进行工具帮助迭代的集合,只要有人引用您尚未迭代的模块,就可以在集合中填写更多数据。