2016-09-01 15 views
-6

私はvectorをループし、毎回アイテムを削除したいと考えています。私はerase-remove idiomを使うべきだと思います。私は、vectoreraseがそのイテレータを無効にすると信じています。その場合、whileループでこのイディオムを使用するにはどうすればよいですか?erase-removeイディオムを使用してループ内のイテレータをインクリメントする方法は?

std::vector<int> vec = { 3, 6, 7, 5 }; 

auto itr = vec.begin(); 
while (itr != vec.end()) 
{ 
    // I'll remove a different element each iteration of the loop. 
    // Hard-coded "7" here for simplicity: 
    auto position = std::remove(vec.begin(), vec.end(), 7); 

    vec.erase(position); 
    ++itr; 
} 

コードの目的はvectorをループにし、素子を毎回削除:

ここで壊れた例です。私はベクトルのサイズが各繰り返しの後に変わるので、whileループとイテレータを使います。各反復で最大の要素を削除しますが、単純化するためにそのコードを表示していません。したがって、要素は7,6,5,3の順番で削除されます。このコードも表示されません。

+2

このコードの目的は何ですか?あなたは 'itr'で何もしていないようです。 –

+1

イレーズイディオムと 'vector :: erase'は異なるものですが、後者は前者を使うかもしれません – jaggedSpire

+0

...リスト内の項目の半分をランダムに削除しようとしていますか? – jaggedSpire

答えて

1

std::remove()単に移動すべての要素(ない一つの要素!)コンテナの最後に、指定された値、および新しい論理過去エンドイテレータを返します。 std::remove()は、アイテムが物理的にが削除されていないため、イテレータを無効にしないので、コンテナのサイズは変更されません。コンテナ内の値だけが移動します。

削除したいものすべてを「削除」したら、最後にerase()を呼び出してに物理的にのアイテムをコンテナから削除します。

これを試してみてください:

std::vector<int> vec = { 3, 6, 7, 5 }; 

auto itr = vec.begin(); 
auto end = vec.end(); 

while (itr != end) 
{ 
    end = std::remove(vec.begin(), end, ...); 
    ++itr; 
} 

vec.erase(end, vec.end()); 
+0

私はwhile(!vec.empty())を実行し、各繰り返しで要素を消去しました。私はこの方法のパフォーマンスについては考えなかった。 – royco

関連する問題