我正在设计一个遍历多个容器的迭代器,因此有一个代理对象作为返回类型。因此,它可以做的最好是成为一个输入迭代器(这是因为前向迭代器需要reference
作为实际的引用类型,而对于输入迭代器来说,这是不正确的)。
(让我说)普通的for_each
就像我的迭代器的魅力一样。
但是,当我查看它的并行版本时,我看到它只接受前向迭代器。因此,我不能使用一个复杂的迭代器来返回一个代理对象,这很烦人。
另一方面,我在线查看其他值得注意的实现,这并不像我最初想象的那样常见 - 例如,英特尔TBB为每个接受输入迭代器的提供了自己的并行。
我的问题是:为什么并行std::for_each
不能与输入迭代器一起使用?
我看不出它们是前向迭代器的重点,因为乍一看它即使使用输入迭代器也应该工作正常。我错过了什么?
由于你指出的原因,C ++ 17迭代器模型存在一个已知的缺陷,即代理迭代器只能是输入迭代器。这有很多缺点。并行算法不需要非代理迭代器,但它们肯定需要多次通过保证。当前的迭代器类别模型将两者混为一谈。
对于C ++ 20范围,我们得到了iterator_concept
的概念,iterator_category
是一个向后兼容的垫片,可以正确支持代理迭代器。你可以有一个input_iterator_tag
的iterator_concept
,但forward_iterator_tag
的ForwardIterator
,例如。新的template<class I>
concept ForwardIterator =
InputIterator<I> &&
DerivedFrom<ITER_CONCEPT(I), forward_iterator_tag> &&
Incrementable<I> &&
Sentinel<I, I>;
概念不考虑该类别,它着眼于这个概念:
for_each
并行算法是否会改变是一个我无法回答的不同问题。
C ++ 17迭代器概念将前向迭代器定义为最弱的迭代器形式,它需要在相同范围内运行多个迭代器。也就是说,您可以复制前向迭代器,增加副本,但仍然可以通过原始迭代器访问原始值。
纯IntputIterator概念只需要单遍。一旦递增迭代器,它的所有其他副本实际上都是无效的。
能够并行化for_each
最终需要每次并行调用以获得一组独特的迭代器和值来进行操作。这意味着迭代器必须是可复制的并且独立于其他迭代器。这需要他们成为前向迭代器。
现在是的,这意味着即使您的迭代器彼此独立,也不能将代理迭代器与并行qazxswpoi一起使用。这只是C ++ 17迭代器概念模型的局限性。