Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建一个不可复制的STL迭代器是一个好主意吗?_C++_Winapi_Stl_Iterator - Fatal编程技术网

C++ 创建一个不可复制的STL迭代器是一个好主意吗?

C++ 创建一个不可复制的STL迭代器是一个好主意吗?,c++,winapi,stl,iterator,C++,Winapi,Stl,Iterator,大多数情况下,STL迭代器是可复制的,因为有几种STL算法需要它来提高性能,例如std::sort 然而,我一直在做一个pet项目来包装FindXFile API(),但问题是不可能围绕这个API实现一个可复制的迭代器。查找句柄不能以任何方式复制--DuplicateHandle明确禁止将这些类型的句柄传递给它。如果只维护对find句柄的引用计数,那么任何副本的单个增量都会导致所有副本的增量——显然,这不是副本构造迭代器应该做的 既然我不能满足这里迭代器的传统复制可构造需求,那么创建一个“STL

大多数情况下,STL迭代器是可复制的,因为有几种STL算法需要它来提高性能,例如
std::sort

然而,我一直在做一个pet项目来包装FindXFile API(),但问题是不可能围绕这个API实现一个可复制的迭代器。查找句柄不能以任何方式复制--
DuplicateHandle
明确禁止将这些类型的句柄传递给它。如果只维护对find句柄的引用计数,那么任何副本的单个增量都会导致所有副本的增量——显然,这不是副本构造迭代器应该做的

既然我不能满足这里迭代器的传统复制可构造需求,那么创建一个“STL风格”迭代器是否值得呢?一方面,创建一些其他枚举方法将不属于正常的STL约定,但另一方面,如果用户稍后尝试复制构造该迭代器,则遵循STL约定将使该迭代器的用户感到困惑


两害孰轻?

不是正向迭代器的输入迭代器是可复制的,但您只能“使用”其中一个副本:增加其中任何副本都会使其他副本无效(取消引用其中一个不会使其他副本无效)。这允许将其传递给算法,但算法必须通过一次传递完成。您可以通过检查算法的要求来判断哪些算法是正确的-例如,
copy
只需要一个inputierator,而
nexture\u find
需要一个ForwardIterator(我找到的第一个)

在我看来,这似乎描述了你的处境。只需复制句柄(或引用句柄的东西),而不复制它

用户必须理解它只是一个输入计算器,但实际上这并不是什么大问题<代码>istream_迭代器是相同的,原因也是相同的


有了C++11的后见之明,要求输入迭代器是可移动的,但不要求它们是可复制的,这几乎是有道理的,因为复制品的用途有限。但这是“有限使用”,而不是“无用”,而且考虑到有多少代码依赖于现有的定义,现在从InputIterator中删除功能已经太迟了。

我不认为复制输入迭代器会使原始迭代器失效(在标准中不是该词的意思)。它确实有副作用(也就是说,如果在
++it2
之前或之后调用,
*it1
的结果可能不同),但AFAIK的任何副本都不会失效。标准中的表72在§24.1.1/2中将
a=u
定义为有效操作,post条件未提及任何无效。§24.1.1/3仅处理输入迭代器中出现的特定行为:
a==b
并不意味着
++a=++b
(即,仅在单次传递算法中有效)要保留输入迭代器的语义,必须在复制的迭代器的不同实例之间共享句柄,并且必须确保在适当的时间释放句柄,而不是更早/更晚。@David:是的。通常我通过使用pimpl习惯用法和不可复制的内部类以及
boost::shared\u ptr
@dribeas:correct来实现这一点。如前所述,复制输入迭代器是允许的。在24.1.1中,表24说明了
运算符+
的post条件:“不再要求
r
先前值的任何副本可以被取消引用或位于
=
的域中。”。我认为“invalidates”是一个合理的总结,尽管它实际上并没有说不能增加前一个值的副本,然后取消引用它。它确实说(1)它不一定给出与您首先递增的结果相同的结果,(2)您“不应该”这样做。学究般地说,如果它不可复制,它就不会是STL迭代器。:)