I am storing an iterator to a list:
list<int> l;
l.push_back(21); l.push_back(1); l.push_back(31); l.push_back(41);
auto it = l.find(21);
In my algorithm, whenever I delete a node, I need to add up the adjoining elements. Something like this:
auto prev = std::prev(it);
auto next = std::next(it);
*prev = *prev + *next;
l.erase(it);
As you see, I need to ensure all boundary conditions. What values do std::prev() and std::next() return if:
it itself has become invalid at some point?What values do
std::prev()andstd::next()return...
They return the nth (where n defaults to 1) predecessor or successor of the iterator it. See here for [iterator.operations] /6 and /7.
... if they are the first and last elements; or if
ititself has become invalid at some point?
The iterator needs to be valid before the call is made. The return value would be an invalid iterator if it is one of the corresponding boundary iterators; i.e. it == begin() for prev(it) and it == end() for next(it).
The validity of it needs to be established before it is used as an argument to prev() or next(). std::prev() and std::next() have no way of determining if the iterator decrement or increment would put the iterator outside the bounds of the container.
As such, it sounds like you would need to code for two boundary conditions in the erase part of the algorithm; first where it == l.begin() and second where it == prev(l.end()), and possibly a third if the element is not found (hence it == l.end()).
// only proceed it something is found...
if (it != l.end()) {
if (it == l.begin()) {
// nothing to do...? element removed is the first one
}
else if (it == std::prev(l.end()) {
// nothing? element removed is the last one....
}
else {
auto prev = std::prev(it);
auto next = std::next(it);
*prev = *prev + *next;
}
l.erase(it); // remove the found element...
}
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