std::equal 是否保证短路?

Is std::equal guaranteed to short circuit?

提问人:ridiculous_fish 提问时间:7/11/2022 最后编辑:Evgridiculous_fish 更新时间:7/11/2022 访问量:172

问:

我想将 nul 终止的字符串与字符串文字进行比较。我希望使用并好奇此代码是否根据 C++ 标准定义良好:std::equal

#include <algorithm>

bool is_foo(const char *str) {
    const char *lit = "foo";
    return std::equal(lit, lit + 4, str);
}

如果保证在第一次不匹配时停止,那么即使长度< 3,对我来说似乎也定义了此代码。如果没有这样的保证,那么我认为这可能会在导致 UB 的结束之后取消引用。std::equalstrstr

如果 C++ 规范对此有什么看法呢?感谢您的帮助!

C++ C++11 比较 语言-律师

评论

0赞 lorro 7/11/2022
AFAIK 仅保证 RandomAccessIterators 的长度比较;在实践中,它很可能会短路。
2赞 n. m. could be an AI 7/11/2022
绝对没有这样的保证。演示
0赞 Peter 7/11/2022
该标准没有规定这样的要求。它确实描述了上限(例如比较次数),但没有说明会导致短路的要求。在实践中,大多数实现可能会以某种方式短路 - 但是它们如何(或是否)这样做是实现质量问题,而不是给定的。

答:

10赞 Sam Varshavchik 7/11/2022 #1

我对 C++ 标准的阅读表明,这是基于以下评论的迂腐的未定义行为:

备注:如果参数列表中没有给出 last2,则表示 first2 + (last1 - first1)。

这是指不提供第二个序列的结束迭代器的重载。在这种情况下,这不是一个有效的指针,因此这是迂腐的未定义行为,给定规范的以下部分:std::equal

E be: pred(*i, *(first2 + (i - first1))) 用于不带参数的重载 项目1;

...

返回: 如果 last1 - first1 != last2 - first2,则返回 false。否则返回 true 如果 E 对 [first1, last1] 范围内的每个迭代器 i 都成立,则为 true,否则, 返回 false。

我在这里看不到任何可以保证短路评估的东西。这种复杂性似乎并不意味着可以保证短路评估:

复杂性:

[ ... ]

...最多 min(last1 - first1, last2 - first2) 应用程序...

“最多”部分没有任何限定。严格解释,这允许但不要求进行短路评估。

评论

7赞 Bill Lynch 7/11/2022
我会比迂腐的未定义走得更远。如果参数对齐且数组是简单的整数,则标准库实现尝试使用更宽的比较指令(例如 64 位或 128 位宽)是合理的。