2017-02-06 8 views
2

私はベクトルv {1、2、3、4、5}を持っているとしましょう。私は最後の2つの要素を削減したいと思いますので、私は、私はのは、このスニペットを見てみましょうC++では、vector :: endに値を代入していますか?

v.end() = v.begin() + 3; 

ような何かしようと思いました。

std::vector<int> v {1,2,3,4,5}; 
std::cout << *(v.end()-1) << std::endl; 
v.end() = v.begin() + 3; 
std::cout << *(v.end()-1) << std::endl; 

これは、両方のケースで5を出力します。何故ですか? vector :: endが反復子を返す場合、それはrvalueではありませんか?もしそうなら、コードはまったくコンパイルすべきではありません。それが左辺値の場合は、最後のイテレータが要素v.begin() + 3を指していないのはなぜですか?

+0

rvalueに割り当てることができるかどうかを知りたい場合は、あまり混乱させない例を使用する必要があります。ベクトルから最後の2つの要素を切り取る方法を知りたければ、おそらくrvalueの要素を削除することができます。この2つの問題はお互いの道に入り、問題を不明瞭にしています。 – juanchopanza

+0

私は未来のことを心に留めておきます。 – user6646922

+0

@元食館:それは完全に公正な発言ではありません。あなたは、質問のある人が問題を完全に理解していないと仮定しなければなりません。上記のコードをC++レベルで使用しているなら、左辺値と右辺値についてのより細かい点を知っていると期待するのは妥当ではありません。あなたはそれが失敗するのを見て、何が起こるかについて推論を開始し、上の質問に終わることがあります。そして、それが実際のコンパイル可能なコードであることを考慮すると、予想された結果と実際の結果が、私はそれがStackOverflowにとって適切であると言います。 – MSalters

答えて

3

v.end()を呼び出すたびに、新しいイテレータオブジェクトが返されます。これは値ですが、値を変更することはできますが、容器には影響しません。v。 ベクターから何かを消去したい場合は、たとえばを使用します。 vector::erase()

+0

あなたはそれが価値であることを意味すると思います。 – juanchopanza

+0

Hm、いいえ?それはオブジェクト(型イテレータ)であり、メモリを占有し、何かを割り当てることができます - >それは左辺値です。 – Rene

+0

これは値です。 'void foo(const vector :: iterator&);'と 'void foo(vector :: iterator &&)'という関数を簡単に書くことで、 'v.end()どの1つの過負荷resulutionがピックアップします。) – juanchopanza

2

消去する必要があるような終了イテレータを割り当てることはできません。

v.erase(v.begin() + 3, v.end()); 
9

std::end()最後後素子を指すイテレータを返します。参照としてのみ使用できます(たとえば、別の反復子を比較するなど)。その値を使用しようとすると、未定義の動作になります。

つまり、このコードv.end() = v.begin() + 3;は、ベクトルから取得したイテレータのコピーの位置を変更するだけで、ベクトル自体は変更されません。

eraseオーバーロードのいずれかを使用して、ベクターの一部を切り詰めることを検討してください。

関連する問題