怎么样*它++对输出迭代器有效吗?

发布于 2024-09-28 16:21:59 字数 202 浏览 6 评论 0原文

在示例代码中,我经常看到诸如 *it++ 之类的输出迭代器代码。表达式*it++ 制作it 的副本,递增it,然后返回最终取消引用的副本。据我了解,制作输出迭代器的副本会使源无效。但是创建副本后执行的 it 增量将是非法的,对吧?我对输出迭代器的理解有缺陷吗?

In example code, I often see code such as *it++ for output iterators. The expression *it++ makes a copy of it, increments it, and then returns the copy which is finally dereferenced. As I understand it, making a copy of an output iterator invalidates the source. But then the increment of it that is performed after creating the copy would be illegal, right? Is my understanding of output iterators flawed?

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

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

发布评论

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

评论(5

孤君无依 2024-10-05 16:21:59

该标准要求 *r++ = t 适用于输出迭代器 (24.1.2)。如果它不起作用,则根据标准的定义,它不是输出迭代器。

由迭代器实现来确保此类语句在幕后正确工作。

不应该保留输出迭代器的多个副本的原因是它具有单遍语义。迭代器只能在每个值处解引用一次(即它必须在每个解引用操作之间递增)。一旦迭代器被取消引用,它的副本就不能被取消引用。

这就是 *r++ = t 起作用的原因。由原始迭代器创建副本,取消引用原始迭代器并递增副本。原始迭代器将永远不会再次使用,并且副本不再引用相同的值。

The standard requires that *r++ = t work for output iterators (24.1.2). If it doesn't work, it's not an output iterator by the standard's definition.

It is up to the iterator implementation to make sure such statements work correctly under the hood.

The reason that you shouldn't keep multiple copies of an output iterator is that it has single pass semantics. The iterator can only be dereferenced once at each value (i.e. it has to be incremented between each dereference operation). Once an iterator is dereferenced, a copy of it cannot be.

This is why *r++ = t works. A copy is made of the original iterator, the original iterator is dereferenced and the copy is incremented. The original iterator will never be used again, and the copy no longer references the same value.

孤独岁月 2024-10-05 16:21:59

表达式*it++(必须)复制它,增加它,等等。
该表达式只是为了方便起见才有效,因为它遵循通常的语义。只有 operator= 执行实际工作。例如,在 ostream_iteratoroperator*operator++operator++(int) 的 g++ 实现中,仅执行 一件事返回*this(换句话说,什么都没有!)。例如,我们可以这样写:

it = 1;
it = 2;
*it = 3;
++it = 4;

而不是: *it++ = 1; *它++ = 2; *它++ = 3; *it++ = 4;

The expression *it++ does not (have to) make a copy of it, does not increment it, etc.
This expression is valid only for convenience, as it follows the usual semantics. Only operator= does the actual job. For example, in g++ implementation of ostream_iterator, operator*, operator++ and operator++(int) do only one thing: return *this (in other words, nothing!). We could write for example:

it = 1;
it = 2;
*it = 3;
++it = 4;

Instead of: *it++ = 1; *it++ = 2; *it++ = 3; *it++ = 4;

巴黎夜雨 2024-10-05 16:21:59

输出迭代器的工作方式与普通迭代器不同,并且指定了它们的接口,以便它们可以在类似指针的表达式 (*it++ = x) 中使用,并产生有用的结果。

通常,operator*()operator++()operator++(int) 都会返回 *this 作为引用输出迭代器有一个神奇的 operator= 来执行预期的输出操作。因为您无法从输出迭代器中读取内容,所以运算符 *() 等不能像其他迭代器一样工作这一事实并不重要。

Output iterators just don't work like normal iterators and their interface is specified so that they can be used in pointer-like expressions (*it++ = x) with useful results.

Typically, operator*(), operator++() and operator++(int) all return *this as a reference and output iterators have a magic operator= which performs the expected output operation. Because you can't read from an output iterator, the fact that operator*() etc., don't work as for other iterators doesn't matter.

苯莒 2024-10-05 16:21:59

看看你的评论,似乎大部分的混乱都来自 SGI 文档,我想说在这一点上有点误导。

复制输出迭代器不会使复制的迭代器无效。真正的限制非常简单:您应该只取消引用输出迭代器的给定值一次。但是,一次拥有两个副本就可以了,只要在它们具有相同值时仅取消引用其中一次即可。在这样的情况下,您取消引用一个值,然后丢弃它的值,并增加另一个值,但仅在增量发生后才取消引用它,这一切都很好。

Looking at your comment, it seems that most of the confusion arises from the SGI documentation, which I'd say is a bit misleading on this point.

Copying an output iterator does not invalidate the copied iterator. The real limitation is pretty simple: you should only dereference a given value of output iterator once. Having two copies at a time, however, is fine as long as you only dereference once of them while they have the same value. In a case like there where you're dereferencing one, then throwing away its value, and incrementing the other but only dereferencing it after the increment has happened, it's all perfectly fine.

十二 2024-10-05 16:21:59

迭代器不就是一个指针吗?递增,然后取消引用它只是移动到下一个元素。

Isn't an iterator just a pointer? Incrementing, then dereferencing it just moves on to the next element.

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