Al.G.
Al.G.

Reputation: 4406

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

Upvotes: 4

Views: 1699

Answers (1)

Barry
Barry

Reputation: 303890

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.

Upvotes: 10

Related Questions