如果使用remove_if,如何删除vector的空单元格

How do delete empty cells of a vector if using remove_if

本文关键字:删除 vector 单元格 何删除 remove if 如果      更新时间:2023-10-16

我正在用某个对象填充std::vector。

这个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());

我很困惑,有人能告诉我怎么做吗?

std::is_empty是一个性状模板。std::is_empty<X>告诉您类型 X是否为空类型—也就是说,它是struct {}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上工作。

或者c++14中的

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

警告

在使用擦除-删除习惯用法时,如果您忘记了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(); } );

很简洁。

c++20标准将std::erase_if添加到语言中。