質問

わかりました、私はここで愚かな間違いを犯したと思います。 displaydevice3dのリストがあり、各displaydevice3dにはdisplaymode3dのリストが含まれています。 displayMode3Dを持たないDisplayDevice3Dのリストからすべてのアイテムを削除したいと思います。私はそれをするためにラムダを使用しようとしています、すなわち。

    // If the device doesn't have any modes, remove it.

  std::remove_if(MyDisplayDevices.begin(), MyDisplayDevices.end(),
   [](DisplayDevice3d& device) 
   { 
    return device.Modes.size() == 0; 
   }
  ); 

MyDisPlayDevicesの6つのdisplayMode3Dのうち、モードコレクションにdisplayMode3Dがあるのは1つだけですが、リストから削除されていません。

私はここでどのような数字の間違いを犯しましたか?

編集:

ああ、私の間違いは、std :: remove_ifの代わりにmydisplaydevices.remove_ifを使用する必要があることでしたが、以下の回答はstd :: remove_if:pの使用に正しいです。

MyDisplayDevices.remove_if( [](DisplayDevice3d const & device) 
                            { 
                                return device.Modes.size() == 0; 
                            });
役に立ちましたか?

解決

remove_ifから返されたiteratorで消去を呼び出す必要があります。次のようになります。

auto new_end = std::remove_if(MyDisplayDevices.begin(), MyDisplayDevices.end(),
                              [](const DisplayDevice3d& device)
                              { return device.Modes.size() == 0; });

MyDisplayDevices.erase(new_end, MyDisplayDevices.end());

他のヒント

remove_if リストから何も削除しません。一緒に使用する必要があります erase. 。これを参照してください 質問 詳細については。

remove_if サイズ変更を実行しませんが、代わりに、削除されていない最後の要素に従う要素に反復器を返すだけです。このイテレーターは渡すことができます erase() クリーンアップを行うために。

enter image description here

他の人が言及したように、それを機能させる方法があります。しかし、私のアドバイスは完全に避けることです remove_if 代わりに標準のイテレーターベースの削除に固執します。以下のイディオムは両方で機能します listvector 予期せぬ動作を生成しません。

for( vector<TYPE>::iterator iter = vec.begin() ; iter != vec.end() ; )
  if( iter->shouldRemove )
    iter = vec.erase( iter ) ; // advances iter
  else
    ++iter ; // don't remove

以下のコメントが言及しているように、この方法はより高いコストを持っています remove_if 複数の要素が削除されたとき。

remove_if ベクトルでさらに先の要素をコピーし、ベクトルの前のベクトルから除去する必要があるベクトルを上書きすることで機能します。例:remove_ifは、すべての0の要素を削除するためにベクトルに呼び出されます。

0 1 1 0 1 0

結果:

1 1 1 0 1 0

ベクトルがまだ正しい方法に注意してください。それが理由です remove_if イテレーターを最後の有効な要素に戻します...ベクトルを自動的にサイズ変更しません。あなたはまだ電話する必要があります v.erase() イテレーターであなたの電話から戻ってきました remove_if.

例を以下に示します

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

void print( vector<int> &v )
{
  for( int i : v )
    printf( "%d ", i );
  puts("");
}

int main()
{
  vector<int> v = { 0, 1, 1, 0, 1, 0 };
  print( v ); // 0 1 1 0 1 0
  vector<int>::iterator it = remove_if( v.begin(), v.end(), [](int i){ return i == 0; } );
  print( v ); // 1 1 1 0 1 0
  v.erase( it, v.end() ); // actually cut out values not wanted in vector
  print( v ); // 1 1 1 (correct)
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top