2016-07-18 13 views
3

std::listの最後の2つの要素のエイリアスが必要です。最後のものは簡単ですが(.back())、前にどのようにしたらいいですか?std :: listの最後の2つの要素への参照を取得する

私の最初のアイデアは、最後の要素(.end())の後に反復子を取得し、それを左に2回動かしたことです。そして、ここで私は「生産」するものである:

&last_but_one = *----myList.end(), 

それは動作しますが、私は個人的にそれを難読化のいくつかの種類を見つけて、私は他の誰かのコードでそれを見た場合、私は簡単にそれを解析とは思わない 。 this answerを読ん

は、いくつかの他は、(あまりにも)冗長アプローチを示しています。

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() 

をこれを行うれる好ましい方法はどれ?

私はコメントを残すことができますが、コードは自明です。選択

答えて

10

std::prev()の主な理由であってはならない 、おそらく遅く、より複雑な
は、2つの引数を取ります。あなたは、第二のいずれかを使用できます。

auto& second_to_last = *std::prev(list.end(), 2); 

これは、それはそう、あなたが1行に必要なすべてを行うことができます代わりにvoidであることの結果として、イテレータを返す以外advance(iter, -2)とバージョンが、まったく同じものを行います。

+0

これは私が考えなかったものです。ドキュメントをチェックしてください。かなりいいね。そして私の状況に完全に通じる。ありがとう! –

+0

ところで、[notes section](http://en.cppreference.com/w/cpp/iterator/prev#Notes)から: "--c.end()の式はしばしばコンパイルされますが、そうすることが保証されています... "あなたの答えにこれを加えることができます。 –

+0

@ Al.G。 'std :: list <>'に対しては、ポインタであるイテレータを取得しません。 – Barry

関連する問題