为什么并行for_each需要前向迭代器?

问题描述 投票:7回答:2

我正在设计一个遍历多个容器的迭代器,因此有一个代理对象作为返回类型。因此,它可以做的最好是成为一个输入迭代器(这是因为前向迭代器需要reference作为实际的引用类型,而对于输入迭代器来说,这是不正确的)。

(让我说)普通的for_each就像我的迭代器的魅力一样。 但是,当我查看它的并行版本时,我看到它只接受前向迭代器。因此,我不能使用一个复杂的迭代器来返回一个代理对象,这很烦人。 另一方面,我在线查看其他值得注意的实现,这并不像我最初想象的那样常见 - 例如,英特尔TBB为每个接受输入迭代器的提供了自己的并行。

我的问题是:为什么并行std::for_each不能与输入迭代器一起使用? 我看不出它们是前向迭代器的重点,因为乍一看它即使使用输入迭代器也应该工作正常。我错过了什么?

c++ language-lawyer std c++17 c++-standard-library
2个回答
10
投票

由于你指出的原因,C ++ 17迭代器模型存在一个已知的缺陷,即代理迭代器只能是输入迭代器。这有很多缺点。并行算法不需要非代理迭代器,但它们肯定需要多次通过保证。当前的迭代器类别模型将两者混为一谈。

对于C ++ 20范围,我们得到了iterator_concept的概念,iterator_category是一个向后兼容的垫片,可以正确支持代理迭代器。你可以有一个input_iterator_tagiterator_concept,但forward_iterator_tagForwardIterator,例如。新的template<class I> concept ForwardIterator = InputIterator<I> && DerivedFrom<ITER_CONCEPT(I), forward_iterator_tag> && Incrementable<I> && Sentinel<I, I>; 概念不考虑该类别,它着眼于这个概念:

for_each

并行算法是否会改变是一个我无法回答的不同问题。


4
投票

C ++ 17迭代器概念将前向迭代器定义为最弱的迭代器形式,它需要在相同范围内运行多个迭代器。也就是说,您可以复制前向迭代器,增加副本,但仍然可以通过原始迭代器访问原始值。

纯IntputIterator概念只需要单遍。一旦递增迭代器,它的所有其他副本实际上都是无效的。

能够并行化for_each最终需要每次并行调用以获得一组独特的迭代器和值来进行操作。这意味着迭代器必须是可复制的并且独立于其他迭代器。这需要他们成为前向迭代器。

现在是的,这意味着即使您的迭代器彼此独立,也不能将代理迭代器与并行qazxswpoi一起使用。这只是C ++ 17迭代器概念模型的局限性。

© www.soinside.com 2019 - 2024. All rights reserved.