§24.1.1/3 from C++03 Standard reads,
For input iterators, a == b does not imply ++a == ++b. (Equality does not guarantee the substitution property or referential transparency.) Algorithms on input iterators should never attempt to pass through the same iterator twice. They should be single pass algorithms. Value type T is not required to be an Assignable type (23.1). These algorithms can be used with istreams as the source of the input data through the istream_iterator class.
I couldn't understand the bold text in the above quotation. Can anyone help me understanding this?
Also, what does the following statement (italicized text in the above quotation) mean? How is it related to a==b
and ++a==++b
expressions?
Equality does not guarantee the substitution property or referential transparency.
Input Iterator is an iterator used to read the values from the container. Dereferencing an input iterator allows us to retrieve the value from the container. It does not alter the value of a container. It is a one-way iterator. It can be incremented, but cannot be decremented.
3. Dereferencing: An input iterator can be dereferenced, using the operator * and -> as an rvalue to obtain the value stored at the position being pointed to by the iterator. 4. Incrementable: An input iterator can be incremented, so that it refers to the next element in the sequence, using operator ++().
Explanation: By definition Input iterators moves sequentially forward. 8. Which of the following is correct about Input Iterators? Explanation: Values cannot be assigned to the location pointed by input operators.
Output Iterator is an iterator used to modify the value in the container. Dereferencing an output iterator allows us to alter the value of the container. It does not allow us to read the value from the container. It is a one-way and write-only iterator.
For Input Iterators, incrementing an iterator invalidates copies of the same iterator.
So:
auto a = istream_iterator<whatever>(something);
auto b = a;
a == b; // true
++a; // b is now invalid
++b; // undefined behavior, I think, but in any case not guaranteed to
// result in anything sensible.
So certainly ++a == ++b
is not guaranteed. That is, a == b
does not imply ++a == ++b
.
I think the "substitution property" means "anything you do with the value of a
has the same result as doing the same with the value of b
", or similar - there are various versions of substitution that it might refer to, but something along those lines. I think in this context it must mean "later doing the same with b
", since if a == b
and I haven't done anything invalid yet, then it doesn't matter which of a
and b
I use, they refer to the same point in the stream. But when I increment, I do have to pick one and lose the other, hence the difficulty with ++a == ++b
.
"Referential transparency" means that different objects are independent, i.e. they're not references/pointers to or aliases of each other. In combination with "substitution property" this means:
Later? There is no earlier or later since operations don't have global side-effects. If you can't substitute "later" then you can't substitute
Input iterators in the same sequence typically refer to the same "actual data", like a file handle or whatever, which itself contains mutable state. Since a
and b
refer to the same file handle, and their value is dependent on its state, you don't have referential transparency. This lack is why substitution fails.
Forward iterators typically also refer to the same underlying data (like a container), but as long as you use them read-only (and don't otherwise modify the container), they don't betray this fact, at least not until you start comparing the addresses of the values they return. So they have a limited kind of referential transparency of their own value, that input iterators don't. They're still references themselves, so the things they refer to are still aliased.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With