STL迭代器相等性是如何建立的?

发布于 2024-07-19 13:44:54 字数 151 浏览 5 评论 0原文

我想知道,STL迭代器的相等(==)是如何建立的? 它是简单的指针比较(因此基于地址)还是更奇特的东西?

如果我有来自两个不同列表对象的两个迭代器并比较它们,结果是否总是错误?

如果我将有效值与超出范围的值进行比较怎么办? 这总是假的吗?

I was wondering, how is equality (==) established for STL iterators?
Is it a simple pointer comparison (and thus based on addresses) or something more fancy?

If I have two iterators from two different list objects and I compare them, will the result always be false?

What about if I compare a valid value with one that's out of range? Is that always false?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

故人的歌 2024-07-26 13:44:55

如果需要,迭代器类可以定义重载的 == 运算符。 所以结果取决于operator==的实现。

您实际上不应该比较来自不同容器的迭代器。 我认为如果您这样做,一些调试 STL 实现会发出警告信号,这将帮助您捕获代码中这种错误使用的情况。

Iterator classes can define overloaded == operators, if they want. So the result depends on the implementation of operator==.

You're not really supposed to compare iterators from different containers. I think some debug STL implementations will signal a warning if you do this, which will help you catch cases of this erroneous usage in your code.

策马西风 2024-07-26 13:44:55

丹尼尔问:
我想知道,STL迭代器的相等(==)是如何建立的? 它是一个简单的指针比较(因此基于地址)还是更奇特的东西?

这取决于实施。 现在,在 Visual C++ 2008 上,我看到以下代码(对于列表迭代器):

bool operator==(const _Myt_iter& _Right) const
{   // test for iterator equality

#if _HAS_ITERATOR_DEBUGGING
    _Compat(_Right);
#else
    _SCL_SECURE_TRAITS_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
#endif /* _HAS_ITERATOR_DEBUGGING */

    return (_Ptr == _Right._Ptr);
}

您将在上面看到,有用于验证迭代器有效性的代码,并且 _Ptr 是指向列表节点。

所以我想既有验证,又有简单的原始指针比较。

丹尼尔问:
如果我有来自两个不同列表对象的两个迭代器并比较它们,结果是否总是 false?

到目前为止,该标准似乎在这个问题上还有些不清楚。 显然,他们会明确地写出这种操作具有未定义的结果:

引用: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#446

使用任何迭代器操作的结果 (24.2.1 [input.iterators], 24.2.2 [output.iterators], 24.2.3 [forward.iterators], 24.2.4 [双向.iterators], 24.2.5 [random.access.iterators]) 使用两个迭代器值作为参数(脚注)从两个不同的范围获得 r1 和 r2 (包括它们的结束值),它们不是一个公共范围的子范围未定义,除非另有明确说明。

脚注)这些操作包括 ==、<、二进制 - 和复制赋值

所以我想比较来自不同容器的迭代器是邪恶的......
^_^

丹尼尔问:
如果我将有效值与超出范围的值进行比较怎么办? 这总是假的吗?

与上面相同。

Daniel asked:
I was wondering, how is equality (==) established for STL iterators? Is it a simple pointer comparison (and thus based on addresses) or something more fancy?

It depends on implementation. Right now, on Visual C++ 2008, I see the following code (for the list iterator):

bool operator==(const _Myt_iter& _Right) const
{   // test for iterator equality

#if _HAS_ITERATOR_DEBUGGING
    _Compat(_Right);
#else
    _SCL_SECURE_TRAITS_VALIDATE(this->_Has_container() && this->_Same_container(_Right));
#endif /* _HAS_ITERATOR_DEBUGGING */

    return (_Ptr == _Right._Ptr);
}

You'll see above that there is both code for verification of iterator validity, and _Ptr being a pointer to a list node.

So I guess there is both verification, and simple, raw pointer comparison.

Daniel asked:
If I have two iterators from two different list objects and I compare them, will the result always be false?

Until now, it appears the standard was somewhat unclear on the subject. Apparently, they will explicitly write that this kind of operation has undefined results:

Quoting: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#446

The result of using any iterator operation (24.2.1 [input.iterators], 24.2.2 [output.iterators], 24.2.3 [forward.iterators], 24.2.4 [bidirectional.iterators], 24.2.5 [random.access.iterators]) that uses two iterator values as arguments (footnote) which were obtained from two different ranges r1 and r2 (including their past-the-end values) which are not subranges of one common range is undefined, unless explicitly described otherwise.

footnote) Among others these operations are ==, <, binary -, and copy assignment

So I guess it is evil to compare iterator from different containers...
^_^

Daniel asked:
What about if I compare a valid value with one that's out of range? Is that always false?

Same as above.

何止钟意 2024-07-26 13:44:55

我想知道,STL迭代器的相等(==)是如何建立的?

并非所有迭代器都可以进行比较(例如,输出迭代器不需要提供 op==)。 当所考虑的迭代器类别的范围概念已明确定义时,您可以使用operator==

这是一个简单的指针比较(因此基于地址)还是更奇特的东西?

迭代器始终使用指针来实现。 编辑:我说实现——这不是指标准要求,而是指使用指针作为底层构造的实践。 不过,实现(如 VS)可能会插入特殊的验证检查。

如果我有来自两个不同列表对象的两个迭代器并比较它们,结果是否总是错误?

您正在调用未定义的行为。

如果我将有效值与超出范围的值进行比较怎么办? 这总是假的吗?

同样,您将调用 UB。 唯一有效的比较是在同一范围内的两个迭代器之间,或者该范围内的一个迭代器与另一个迭代器与最后一个元素之后的迭代器之间的比较。 请注意,您只能将迭代器与最后一个元素进行比较,取消引用相同的元素会导致 UB。

I was wondering, how is equality (==) established for STL iterators?

Not all iterators can be compared (e.g. Output Iterators are not required to provide op==). You can use the operator== when the concept of a range is well-defined for the iterator category under consideration.

Is it a simple pointer comparison (and thus based on addresses) or something more fancy?

Iterators are always implemented with pointers. Edit: I say implemented with -- which refers not to a Standard requirement but rather to the practice of using poitners as the underlying construct. Implementations (like VS) may have special validation checks inserted though.

If I have two iterators from two different list objects and I compare them, will the result always be false?

You are invoking Undefined Behavior.

What about if I compare a valid value with one that's out of range? Is that always false?

Again, you will be invoking UB. The only valid comparison are between two iterators in the same range or between one in the range and another to one past the last element. Note, you can only compare against the iterator to one-past the last element, dereferencing the same leads to UB.

雅心素梦 2024-07-26 13:44:55

相等测试特定于您正在使用的迭代器类型,或者可能根本不存在。 如果你真的想知道,你可以随时检查你正在使用的STL实现的源代码,在迭代器类中查找operator==()。

迭代器并不总是指针,实际上在 STL 的某些“安全”版本中,迭代器从来都不是指针。 向量和字符串的迭代器通常被实现为指针,因为它们可以。 双端队列、列表、集合和映射的迭代器在任何半效率实现中都不能是指针。

迭代器是一种智能指针。 它们遵循这样的通用原则:如果它们的外观和行为都像指针,那么对于用户而言,它们就是指针。

The equality test is specific to the type of iterator you are using, or may not exist at all. If you really want to know, you can always check the source code of the implementation of STL you are using, look for operator==() in the iterator class.

Iterators are NOT always pointers, and indeed in some "safe" versions of the STL, are never pointers. Iterators for vectors and strings are commonly implemented as pointers because they can be. Iterators for deques, lists, sets and maps cannot be pointers in any half efficient implementation.

What iterators are is a type of smart pointer. They follow the generic principle that if they look and behave like a pointer, then they are a pointer as far as the user is concerned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文