C++ 值初始化向量迭代器比较

C++ value initialized vector iterator comparison

下面的代码在c++17中合法吗?

std::vector<int> x{1,2,3};
std::vector<int>::iterator it{};
bool result = x.begin() != it;

以下内容转自https://en.cppreference.com/w/cpp/named_req/ForwardIterator :

Equality and inequality comparison is defined over all iterators for the same underlying sequence and the value initialized-iterators

如果我没看错的话,对比一下应该没问题。它似乎适用于 clang 和 gcc,但是当我在调试模式下使用 MSVC 2019 运行 时,我得到一个断言说 "vector iterators incompatible"。

我不是问比较的结果,我只关心 MSVC 是否符合这里的标准。

godbolt

上的实例

MSVC 符合要求。

通常只能将相同序列的迭代器相互比较。值初始化的迭代器被认为是相同空序列的迭代器。 "virtual" 空序列不同于任何其他序列,并且未(要求)定义不同序列之间的比较,因此该示例可能未定义。

标准报价(最新稿)

[forward.iterators] The domain of == for forward iterators is that of iterators over the same underlying sequence. However, value-initialized iterators may be compared and shall compare equal to other value-initialized iterators of the same type. [ Note: Value-initialized iterators behave as if they refer past the end of the same empty sequence. — end note

不保证向量迭代器在比这更广泛的域中实现比较。如果没有,则行为未定义。您的比较在此域之外。

Visual Studio 是正确的。你得到一个断言(仅在调试中!)因为你的代码有未定义的行为,并且实现警告你。

值初始化迭代器只能与其他值初始化迭代器进行比较。这是比较指针或迭代器仅在序列或数组中起作用的规则的概括(一个值得注意的例外是 std::less,它轻松地提供了整个内存的总排序 space;这是只有使用默认比较器的不相关指针的集合才能工作。

[forward.iterators] The domain of == for forward iterators is that of iterators over the same underlying sequence. However, value-initialized iterators may be compared and shall compare equal to other value-initialized iterators of the same type. [ Note: Value-initialized iterators behave as if they refer past the end of the same empty sequence. — end note ]

没有为值初始化迭代器和序列中某个位置的迭代器之间的排序定义任何语义。

cppreference 文本在这方面的措辞有点糟糕,尽管同一页面在两个单数迭代器之间成功相等的语义上确实做得更好:

A value-initialized LegacyForwardIterator behaves like the past-the-end iterator of some unspecified empty container: it compares equal to all value-initialized LegacyForwardIterators of the same type.

同样,您不能将迭代器与不同的容器进行比较,因此我们有自己的规则。