Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are C++ iterators required to return a reference?

I'm implementing an iterator that iterates over the results of a generator function rather than over a data structure in memory such as a vector or map.

Reading through the final working draft for C++17 §27.2.3, the return type of the dereference operator for an input iterator (and by extension, most other iterators) a forward iterator is required to be a reference. This is fine for items that exist in the data structure the iterator is iterating over. However, because I'm not using a data structure and am calculating each item when the dereference operator is called, I don't have a valid reference to return; the calculated item is destroyed when the operator returns. To work around this, I am storing the result of the calculation in the iterator itself and returning a reference to the stored result. This works fine for my use case, but has issues of its own when used with arbitrary user-defined types.

I can understand iterators being allowed to return a reference, but why would this be a requirement for non-mutating iterators? Did the writers of the standard not consider generators and on-the-fly transformations to be valid use cases for iterators? Would returning a value instead of a const reference cause any actual harm?

[edit]: I'm asking more out of curiosity about why the standard is written the way it is, since I already have a perfectly good workaround.

like image 573
Christopher van Zomeren Avatar asked Oct 08 '17 01:10

Christopher van Zomeren


People also ask

Does iterator return reference?

3, the return type of the dereference operator for an input iterator (and by extension, most other iterators) a forward iterator is required to be a reference. This is fine for items that exist in the data structure the iterator is iterating over.

What is iterator in C?

An iterator is an object that allows you to step through the contents of another object, by providing convenient operations for getting the first element, testing when you are done, and getting the next element if you are not. In C, we try to design iterators to have operations that fit well in the top of a for loop.

Is an iterator a pointer C++?

Introduction to Iterators in C++ An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container.

How is iterator implemented in C++?

The iterator is implemented as a pointer to a node, and contains operator overloads for the four usual iterator operations of dereference, increment, comparison, and assignment. in the list class that can be used to insert new data items at arbitrary locations in the list.


1 Answers

Dereferencing an input iterator is not required to yield a glvalue (that is, return a reference). The input iterator requirements say that the return type when dereferencing must be "reference, convertible to T" but nowhere does it say that reference must be a reference type.

However, dereferencing a forward iterator is required to yield a glvalue:

if X is a mutable iterator, reference is a reference to T; if X is a constant iterator, reference is a reference to const T,

So go ahead and write your iterator that generates elements on the fly, but it can only be an input iterator, not a forward iterator. For many algorithms this is sufficient (e.g., std::for_each and std::all_of).

like image 170
Brian Bi Avatar answered Oct 17 '22 15:10

Brian Bi