Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get references to the last two elements in std::list

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

like image 236
Al.G. Avatar asked Dec 25 '22 03:12

Al.G.


1 Answers

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.

like image 164
Barry Avatar answered Jan 04 '23 22:01

Barry