How is *it++ valid for output iterators?

蓝咒 提交于 2019-12-21 07:34:44

问题


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?


回答1:


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;




回答2:


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.




回答3:


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.




回答4:


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.




回答5:


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



来源:https://stackoverflow.com/questions/4001517/how-is-it-valid-for-output-iterators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!