2

std::vector にオブジェクトを入力しています。

次の行で定義されているこのベクター インスタンス:

std::vector< std::list< pcl::PointXYZRGB>> tab;

空のセルを削除したいと思います。私は次のように試しました:

tab.erase(remove_if(tab.begin(), tab.end(), std::is_empty), tab.end());

次のエラーが表示されます。

error: missing template arguments before ‘)’ token
     voxels.erase(remove_if(voxels.begin(), voxels.end(), is_empty**)**, voxels.end());

私は混乱しています、誰かが私にそれを行う方法を教えてもらえますか?

4

1 に答える 1

6

std::is_empty特性テンプレートです。 が空std::is_empty<X>の型であるかどうかを示します。つまり、 orであり、内部に何もありません Xstruct {}class {}

これはあなたが望むものではありません。第一に、必要な方法で呼び出すことができないためoperator()です-あなたにとって有用なものはありません-第二に、型のインスタンスではなく型を取り、型に関する質問に答えます。インスタンス。

auto list_is_empty = [](std::list<pcl::PointXYZRGB> const& l) {
  return l.empty();
};
tab.erase(std::remove_if(tab.begin(), tab.end(), list_is_empty), tab.end());

あなたの問題を解決します。それを解決するより良い方法は次のとおりです。

struct container_is_empty_t {
  template<class C>
  bool operator()(C const& c)const{
    return c.empty();
  }
  // not really needed, arrays of size 0 are non-standard
  template<class T, size_t N>
  bool operator()(T(&)[N])const{
    return N > 0;
  }
};
static container_is_empty_t const container_is_empty;

ユーティリティコードを含むヘッダーファイルで、次のようにします。

tab.erase(std::remove_if(tab.begin(), tab.end(), container_is_empty), tab.end());

同じことを行いますが、std::list< pcl::PointXYZRGB>s でのみ動作するようにハードコードされていません。

またはで:

tab.erase(std::remove_if(tab.begin(), tab.end(), [](auto&& c){ return c.empty(); }, tab.end());

警告

erase-remove イディオムを実行するときに、その部分を忘れると、tab.end()コンパイルはできても、病的な方法で完全に間違ったことを実行するコードが得られます。

持っているのが一番いいと思います

// erases elements from sequential container C if f(element) is true:
template<class C, class F>
auto erase_if( C& c, F f ) {
  using std::begin; using std::end;
  auto it = std::remove_if( begin(c), end(c), std::move(f) );
  auto sz = std::distance( it, end(c) );
  c.erase( it, end(c) );
  return sz;
}

その危険を回避するためのヘルパー関数。

次に、次のようになります。

erase_if( tab, [](auto&& c){ return c.empty(); } );

これは素晴らしく短いです。

標準が言語に追加されstd::erase_ifます。

于 2015-09-15T18:02:23.637 に答える