Let’s suppose I have a singly-linked list alike std::forward_list. I would like to find a single list element matching the predicate, perform a few operations on it and optionally remove it based on another predicate.
So far, I’ve assembled the following:
for (T::iterator it = l.begin(), prev_it = l.before_begin();
it != l.end();)
{
if (predicate)
{
// ...
if (another_predicate)
{
l.erase_after(prev_it);
break;
}
}
prev_it = it;
++it;
}
However, I’m especially wondering if it’s the most optimal way of performing the increment part. Alternatively, I have been considering:
++prev_it;
++it;
While in plain C the former would be obviously better, in C++ that seems not that clear anymore. I believe that with simpler iterators, the former should be simpler; however, if copying the iterator may involve memory allocation (e.g. when using PImpl), the latter may actually be better.
Which method do you consider superior and why? Please note that I’d like to avoid limiting this strictly to a common std::forward_list design and consider a solution which would work with more complex types.
I get really confused when for-loops don’t increment their counters, so I would simply add
++prev_it, ++itto your for-loop. Your iterators will stay in lockstep (provided you don’t mess with them) and the names clearly state what they refer to. I always err on the side of clarity before worrying about performance.You probably shouldn’t worry about generalizing this code to other containers because
std::forward_listis a special case. Other containers don’t require things likeerase_after.