eepp eepp - 29 days ago 9
C++ Question

In C++, is it okay to implement an iterator interface in which advancing invalidates the "current" element?

I'm designing a C++ interface which allows the user to iterate on objects decoded from a file. This decoding process is somewhat slow.

I'm considering an iterator interface for this, but I want to avoid any unnecessary copy, so I'm thinking about (user's side):

for (const auto& object : file) {
// you can access the members of `object` here
std::cout << object.whatever() << std::endl;

// you can copy `object` here
myObjectCopy = object;

// you CANNOT do this because `object` changes
// as soon as the iterator advances
myObjectPtr = &object;
}


object
in the previous usage example is a reference to an object internal to the iterator instance.

Is this wrong? What other idiomatic interfaces would you suggest here?

I thought about a stream interface (think
std::istream
), but AFAIK, the methods to read data also return copies (they extract characters).

Answer

Sounds like what you're talking about is an input iterator.

Be sure to inherit your custom iterator class from std::iterator<std::input_iterator_tag, decoded_object_type>. A classical implementation is for operator* to cache the decoded object, and return the cached object if it's invoked a second time before operator++ gets invoked; and operator++ invoking operator* to make sure that the object gets decoded, if it's not already.

Comments