【问题标题】:Is std::any_of required to follow short circuit logic?是否需要 std::any_of 遵循短路逻辑?
【发布时间】:2018-05-21 09:22:06
【问题描述】:

给定以下代码,

std::vector<int> numbers = {1, 2, 3, 4, 5};
std::any_of(std::begin(numbers), std::end(numbers), 
            [](int number) { return number > 3; } );

std::any_of 是否需要(按标准)在达到 4 时立即返回?

【问题讨论】:

  • 即:很明显它应该在知道决定后立即返回,但必须吗?不过,我真的不明白为什么需要问这些问题,而不仅仅是阅读标准来了解。
  • 虽然这在概念上类似于对所有元素的谓词结果进行 ORing,但在大多数情况下,它可能不会使用 operator || 展开为单个语句,所以我不认为这确实表明短路是否会以任何一种方式发生......虽然可以肯定,常识确实如此。
  • @underscore_d:我不相信这一点。在我撰写本文时,唯一的答案似乎排除了 C++ 标准库对排序容器的潜在优化。否则将使用 O(log N) 类型的方法。它仍然可以,但它必须沿着容器向后跟踪以挑选出满足条件的第一个元素。正是这种细节使这个问题成为一个非常好的问题
  • 致投票结束此事件的人主要基于意见:什么?

标签: c++ c++11 stl language-lawyer


【解决方案1】:

标准本身并没有提出任何这样的硬性要求。但可以推断它是间接鼓励的([alg.any_of]):

template <class InputIterator, class Predicate>
  bool any_of(InputIterator first, InputIterator last, Predicate pred);
template <class ExecutionPolicy, class ForwardIterator, class Predicate>
  bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
              Predicate pred);

返回:如果 [first, last) 为空或者如果 [first, last) 范围内没有迭代器 i 使得 pred(*i) 为真,则为假,并且为真 否则。

复杂性:至多最后 - 谓词的第一次应用。

虽然完全符合的实现可能会应用谓词完全 last-first 次,但在我看来,这种措辞听起来像是鼓励尽快退出。

请注意,几乎不可能询问接受ExecutionPolicy 的重载。从那时起,评估的顺序就不得而知了。

在不太正式的说明中,任何在谓词为真时退出的顺序版本的实现都会对其作者的凭据产生质疑。

【讨论】:

  • 该标准不应该强制要求确切的顺序和计数,因为它可能会排除依赖于容器和谓词类型的优化。例如。 any_of(begin(intSet), end(intSet), [](int i) { return i &gt; 500 &amp;&amp; i &lt; 1000; }) 可以翻译成涉及intSet.upper_bound(500); 的东西。或者容器(部分)是连续的,编译器生成 SIMD。或者有一个不同的顺序可以更有效地访问容器元素。如果谓词没有副作用,那么所有这些都将在 as-if 规则下运行。
  • 让我感兴趣的是 [alg.any_of]“非修改序列操作” [alg.nonmodifying] 部分中,但没有什么不允许使用不纯谓词:any_of(begin(numbers), end(numbers), [](int&amp; number) { return --number &gt; 2; } )。 gcc 和 clang 实现在到达范围末尾之前会停止。
  • @YSC - 他们在那个部分,因为他们只接受一个谓词。 And well... 违反不应要求通常只是 UB 的承诺。
  • @YSC - 让我困惑的是std::for_each 也在那里。因为它不限于接受一个普通的谓词。
  • @YSC - 实际上,你我都误解了。该部分被称为“非修改”,因为所有算法都在适当的位置工作。 “修改”部分具有产生输出范围的算法(通过 otuput 迭代器)。
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多