【问题标题】:How do delete empty cells of a vector if using remove_if如果使用 remove_if,如何删除向量的空单元格
【发布时间】:2015-09-15 17:37:41
【问题描述】:

我正在用一些对象填充 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());

我很困惑,谁能告诉我该怎么做?

【问题讨论】:

  • 在询问有关堆栈溢出的问题时,提供足够的信息以供回答是很重要的。您应该做的第一步是尝试将您的问题减少到更小的问题。你不明白eraseremove_if 是如何工作的;所以创建一个使用这些函数的小程序,看看你是否会得到同样的错误。您可以通过从完整程序开始并删除部分来做到这一点,或者从一个空程序开始并添加部分。一旦您有了一个简单、自包含和完整的示例,您就可以询问该问题。跨度>
  • @T.C. OP 在下面的评论中回答了您的问题:std::is_empty 是她试图使用的。好老using namespace std,是不是很可怕?

标签: c++ c++11 vector erase remove-if


【解决方案1】:

std::is_empty 是一个特征模板。 std::is_empty&lt;X&gt; 告诉您类型 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&lt; pcl::PointXYZRGB&gt;s 上工作。

或在

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(); } );

又好又短。

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

【讨论】:

  • 从技术上讲,它有一个 operator() - 继承自 integral_constant :)
  • 很快就会出现在你身边的 TS:统一擦除:erase_if(tab, container_is_empty)
  • @TemplateRex 我已经有了自己的版本,所以无需等待。作为奖励,我的erase_if 还允许您在迭代时修改条目! (简单地说“它定义明确”,而不是调用std::erase_if(可悲),而如果你调用std::erase_if,标准会说“没有cookie给你”)。
猜你喜欢
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
  • 2022-11-24
  • 2019-06-18
  • 2011-12-19
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
相关资源
最近更新 更多