根据en.cppreference.com和VC ++ 14.0,迭代器需要有复制构造函数和复制赋值运算符。
我的迭代器类(它遍历Windows进程)无法进行可复制构建或可复制分配 - 它为快照保存HANDLE
并管理释放它,因此不可能复制那些 - 移动它们是可能的,我提供了一个移动构造函数和移动赋值运算符。但是,算法std::find_if
复制它们(在VC ++ 14.0中调用了一些std::_Find_if
,这需要复制迭代器)并且不想工作。
为什么你的迭代器会占用资源?迭代器应该像指针指向某个东西。
因为为了遍历Windows进程,您需要创建一个快照,然后使用它来执行此操作 - 问题是,一个快照,一个迭代。快照也不可复制。
为什么他们只能MoveConstructible
和MoveAssignable
?哪些算法(如果有的话)真的需要复制迭代器才能工作?
答案 0 :(得分:3)
迭代器不应该拥有资源;它们是指针的抽象,应该便宜复制。整个标准库假定这一点。
使用单独的(仅限移动)课程来管理HANDLE
;你的迭代器应该存储一个指向该类的指针。
答案 1 :(得分:3)
TL; DR:由于历史原因。
我认为,ForwardIterator
和其他更多功能迭代器需要可复制的原因或多或少都是显而易见的。至于InputIterator
和OutputIterator
,情况有点复杂。
InputIterator
和OutputIterator
具有一次通过性质,与仅移动类概念非常吻合。现在,当您使用标准库中的任何这些迭代器时(例如,让它说出istream_iterator
),您可以复制它并取消引用副本,但可以推进任何副本会推进所有这些,这看起来不像预期的行为。
不幸的是,在编写许多STL算法(如std::find_if
,std::copy
等)时,根本没有移动语义,也没有办法要求{{1可移动构造。
从那时起,在某些平台上,STL算法实际上要求迭代器是可复制的(如本例所示),而在其他平台上(如g ++ AFAIK),InputIterator
的概念需要这种行为。每次使用STL算法时都要在编译时检查。
此外,您可能会发现this answer有用。
答案 2 :(得分:-1)
那么,他们怎么可能不是? 最简单的查找可能看起来像这样:
for (IT i = begin_iterator, e = end_iterator; i != e; ++i)
它将如何构建我?