std::equal 是否保证短路?

rid*_*ish 6 c++ comparison language-lawyer c++11

我想将以 null 结尾的字符串与字符串文字进行比较。我希望使用std::equal并且很好奇这段代码是否根据 C++ 标准定义良好:

#include <algorithm>

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

如果std::equal保证在第一个不匹配处停止,那么即使str长度 < 3,这个代码对我来说似乎也是定义的。如果没有这样的保证,那么我认为这可能会取消引用超过str导致 UB 的末尾。

如果 C++ 规范对此有任何规定怎么办?谢谢你的帮助!

Sam*_*hik 10

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

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

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

E 是: pred(*i, *(first2 + (i - first1))) 对于没有参数 proj1 的重载;

...

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

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

复杂:

[...]

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

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

  • 我会比_迂腐地未定义_走得更远。如果参数对齐并且数组是简单整数,那么标准库实现尝试使用更宽的比较指令(例如 64 或 128 位宽)是合理的。 (7认同)