为什么迭代器需要是CopyConstructible和CopyAssignable?

时间:2015-08-28 16:56:17

标签: c++ iterator

根据en.cppreference.com和VC ++ 14.0,迭代器需要有复制构造函数和复制赋值运算符。

我的迭代器类(它遍历Windows进程)无法进行可复制构建或可复制分配 - 它为快照保存HANDLE并管理释放它,因此不可能复制那些 - 移动它们是可能的,我提供了一个移动构造函数和移动赋值运算符。但是,算法std::find_if复制它们(在VC ++ 14.0中调用了一些std::_Find_if,这需要复制迭代器)并且不想工作。

  

为什么你的迭代器会占用资源?迭代器应该像指针指向某个东西。

因为为了遍历Windows进程,您需要创建一个快照,然后使用它来执行此操作 - 问题是,一个快照,一个迭代。快照也不可复制。

为什么他们只能MoveConstructibleMoveAssignable?哪些算法(如果有的话)真的需要复制迭代器才能工作?

3 个答案:

答案 0 :(得分:3)

迭代器不应该拥有资源;它们是指针的抽象,应该便宜复制。整个标准库假定这一点。

使用单独的(仅限移动)课程来管理HANDLE;你的迭代器应该存储一个指向该类的指针。

答案 1 :(得分:3)

TL; DR:由于历史原因。

我认为,ForwardIterator和其他更多功能迭代器需要可复制的原因或多或少都是显而易见的。至于InputIteratorOutputIterator,情况有点复杂。

InputIteratorOutputIterator具有一次通过性质,与仅移动类概念非常吻合。现在,当您使用标准库中的任何这些迭代器时(例如,让它说出istream_iterator),您可以复制它并取消引用副本,但可以推进任何副本会推进所有这些,这看起来不像预期的行为。

不幸的是,在编写许多STL算法(如std::find_ifstd::copy等)时,根本没有移动语义,也没有办法要求{{1可移动构造。

从那时起,在某些平台上,STL算法实际上要求迭代器是可复制的(如本例所示),而在其他平台上(如g ++ AFAIK),InputIterator的概念需要这种行为。每次使用STL算法时都要在编译时检查。

此外,您可能会发现this answer有用。

答案 2 :(得分:-1)

那么,他们怎么可能不是? 最简单的查找可能看起来像这样:

for (IT i = begin_iterator, e = end_iterator; i != e; ++i)

它将如何构建我?