简体   繁体   English

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

[英]C++ value initialized vector iterator comparison

Is the following code legal in c++17? c++17 中的以下代码是否合法?

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

The following is quoted from https://en.cppreference.com/w/cpp/named_req/ForwardIterator :以下引自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相等和不等比较是在相同底层序列的所有迭代器和值初始化迭代器上定义的

If I understand this correctly, the comparison should be ok.如果我理解正确的话,比较应该没问题。 And it seems to work on clang and gcc, but when I run this with MSVC 2019 in debug mode, I get an assert saying "vector iterators incompatible".它似乎适用于 clang 和 gcc,但是当我在调试模式下使用 MSVC 2019 运行它时,我得到一个断言说“向量迭代器不兼容”。

I'm not asking about the outcome of the comparison, I'm only interested if MSVC is conforming to the standard here.我不是在询问比较的结果,我只对 MSVC 是否符合此处的标准感兴趣。

Live example on godbolt Godbolt上的实时示例

MSVC is conforming. MSVC 符合要求。

Only iterators to the same sequence may generally be compared with one another.只有同一序列的迭代器通常可以相互比较。 Value initialised iterators are considered to be iterators to the same empty sequence.值初始化的迭代器被认为是相同空序列的迭代器。 That "virtual" empty sequence is distinct from any other sequence, and comparisons across separate sequences are not (required to be) defined, and thus the example is potentially undefined.该“虚拟”空序列与任何其他序列不同,并且未(必须)定义跨单独序列的比较,因此该示例可能未定义。

Standard quote (latest draft)标准报价(最新草案)

[forward.iterators] The domain of == for forward iterators is that of iterators over the same underlying sequence. [forward.iterators] 前向迭代器的 == 域是相同底层序列上的迭代器的域。 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 ——尾注

Vector iterators are not guaranteed to implement the comparison for a wider domain than this.向量迭代器不能保证实现比这更宽的域的比较。 If it doesn't, then the behaviour is undefined.如果没有,则行为未定义。 Your comparison is outside of this domain.您的比较不在此域范围内。

Visual Studio is correct. Visual Studio 是正确的。 You are getting an assertion (in debug only!) because your code has undefined behaviour , and the implementation is warning you about that.您正在获得一个断言(仅在调试中!),因为您的代码具有未定义的行为,并且实现正在警告您。

Value-initialised iterators can only be compared to other value-initialised iterators.值初始化的迭代器只能与其他值初始化的迭代器进行比较。 This is a generalisation of the rule that comparing pointers or iterators only works within a sequence or array (with one notable exception being std::less , which handily provides a total ordering over the whole memory space; this is the only way a set, using the default comparator, of unrelated pointers can work).这是比较指针或迭代器仅适用于序列或数组的规则的概括(一个值得注意的例外是std::less ,它方便地提供整个 memory 空间的总排序;这是集合的唯一方法,使用默认比较器,不相关的指针可以工作)。

[forward.iterators] The domain of == for forward iterators is that of iterators over the same underlying sequence. [forward.iterators] 前向迭代器的 == 域是相同底层序列上的迭代器的域。 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 ] ——尾注]

No semantics are defined for an ordering between a value-initialised iterator, and an iterator to a position in a sequence.没有为值初始化迭代器和序列中 position 的迭代器之间的排序定义语义。

The cppreference text is a little badly-worded in this regard, though the same page does do a little better on the semantics for a successful equality between two singular iterators:在这方面,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.值初始化的LegacyForwardIterator的行为类似于某个未指定空容器的结束迭代器:它与相同类型的所有值初始化的 LegacyForwardIterator 进行比较。

And, again, you cannot compare iterators to different containers, so there we have our rule.而且,你不能将迭代器与不同的容器进行比较,所以我们有我们的规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM