tags:

views:

119

answers:

5

I'm writing a custom iterator for a Matrix class, and I want to implement the increment method, which gets called when the iterator is incremented:

void MatrixIterator::increment()
{
    // go to the next element
}

Suppose the iterator has been incremented too many times and now points to past the end of the matrix (i.e. past the one-past-the-end point). What is the best practice for this situation? Should I catch this with an assert, or should I just say it's the user's responsibility to keep track of where the iterator is pointing and it's none of my business?

+4  A: 

You can assert, but in general you are not required to do anything. C++ iterators are not supposed to catch errors. E.g. STL iterators don't do that.

doublep
+1. Nobody is ever required to assert anything… but this is the classic case where you should if you can.
Potatoswatter
What about checked implementations of the STL? All decent STL implementations have checked/debug versions which do assert when you increment past end.
AshleysBrain
GCC doesn't seem to have. So it's not a decent implementation?
UncleBens
A: 

You don't have to handle it at all. If an iterator has been incremented past container::end(), then that invokes undefined behavior. Even if it crashes, that's still legal according to STL semantics.

EDIT: Put another way:
[S]hould I just say it's the user's responsibility to keep track of where the iterator is pointing and it's none of my business?
Yes.

Billy ONeal
Why the downvote?
Billy ONeal
A: 

Are you sure your matrix class actually has to have an iterator? The best practice when coding matrixes, as far as I know, is overloading operator () so that it works as double indexer and leaving it at this stage.

Still, if you want to, then leave it as it is / put an assert. Generally speaking, the second variant is not necessary, but this is how it's done in STL. I'm pretty sure you've seen asserts in MSVS shouting iterator not dereferencable...

edit Looks like it's the place where I f*cked up. There is no assert in STL when an iterator overcomes the end and the not dereferencable assert is located in the other place...

Kotti
@Kotti: But the standard does not *require* that the compiler or STL implementation complain. It'd be just as valid a response to format the user's hard disk.
Billy ONeal
A: 

Typically when a C++ iterator moves beyond the end of the container the value of the iterator is set to a value that equals the value returned by end().

So

iterator++;
if ( iterator == container.end() )
{
   // break from loop
}

By the looks of it, end can be any value you want.

gbrandt
where is this sort of functionality implemented?
Goose Bumper
I am/was assuming that you were using STL, since you used the word iterator. end() is implemented in the iterator itself.
gbrandt
+1  A: 

You don't have to do anything, but it can be really helpful to assert there. Anyone using your code who increments an iterator past the end has a bug. If you do nothing, you probably invoke undefined behavior, which can include the program appearing to work correctly, but crashing under rare and difficult circumstances. That's nasty. If you assert, developers using your code can find problems much more easily.

Note that most major compilers provide checked (or debug) versions of the STL, which includes asserting when you increment iterators past end, use invalidated iterators, etc. This is really helpful since you get debug asserts instead of undefined behavior in these cases, and it all compiles out of release builds. While you're allowed to not care, and the STL authors are allowed to not care, it's very helpful to put those diagnostics in.

AshleysBrain