3

C++ラムダ関数を学んでいますが、このおそらく簡単な問題がいくつかの問題を引き起こしています。

いくつかの整数を含むベクトルがあります。偶数をすべて削除しようとしています。

現在、偶数を削除していますが、ベクターの内容を印刷すると、ベクターの最後に繰り返しデータが残ります。

int main()
{
  std::vector<int> v1 = {0,1,1,2,3,5,8,13,21,55,89};

  for (const auto &i : v1) std::cout<< i << " ";
  std::cout<<std::endl; 

  v1.erase(std::remove_if(v1.begin(), v1.end(), [](int i)
       { return (i % 2) == 0; }));

  for (const auto &i : v1) std::cout<< i << " ";
}

出力:

0 1 1 2 3 5 8 13 21 55 89 
1 1 3 5 13 21 55 89 55 89

2行目の出力を次のようにしたい:

1 1 3 5 13 21 55 89

編集

みんな、ありがとう。私は間違ったバージョンの消去を使用していました (今では非常にばかげているように感じます)。正しいコードは次のとおりです。

int main()
{
  std::vector<int> v1 = {0,1,1,2,3,5,8,13,21,55,89};

  for (const auto &i : v1) std::cout<< i << " ";
  std::cout<<std::endl; 

  v1.erase(std::remove_if(v1.begin(), v1.end(), [](int i)
       { return (i % 2) == 0; }), v1.end());

  for (const auto &i : v1) std::cout<< i << " ";
}
4

1 に答える 1

6

std::vector::erase単一のイテレータを取るオーバーロードを使用しています。

これは望ましいオーバーロードです:

iterator erase(const_iterator first, const_iterator last);

あなたがやろうとしていることはこれです:

auto is_even = [](int i) { return (i % 2) == 0; };
v1.erase(std::remove_if(v1.begin(), v1.end(), is_even), v1.end());

firstこのオーバーロードは、との間の要素を消去しますlast

std::remove_if述語関数によって定義された条件を満たさない要素のみが含まれるように範囲を変更します。次に、イテレータを範囲の新しい末尾に返します。

Erase は、コンテナから要素を実際に削除することでジョブを終了します。

于 2013-10-09T21:47:59.060 に答える