I need aliases of the last two elements in an std::list
. The last one is easy (.back()
), but how should I get the one before it?
My first idea was: get an iterator after the last element (.end()
) and the move it twice to the left. And here is what I "produced":
&last_but_one = *----myList.end(),
Although it works, I personally find it some kind of obfuscated and I don't think I would parse it easily if I saw it in someone else's code1.
Reading through this answer shows some other (too) verbose approaches2:
auto iter = n.end();
std::advance(iter, -2);
&last_but_one = *iter; // this is overkill!
// weird, and the .next() variant even more
&last_but_one = *std::prev(std::prev(n.end()));
&last_but_one = *++myList.rbegin(); // similar to *----myList.end()
Which is the prefered way of doing this?
1I could leave a comment but code should be self-explanatory.
2 and probably slower and more complex, which shouldn't be the main reason for the choice
std::prev()
takes two arguments. You can use the second one:
auto& second_to_last = *std::prev(list.end(), 2);
This does exactly what your version with advance(iter, -2)
does, except it returns the resulting iterator instead of being void
so you can do everything you need on one line.
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