如果使用 remove_if 如何删除向量的空单元格
How do delete empty cells of a vector if using remove_if
我正在用一些对象填充 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());
我很困惑,谁能告诉我该怎么做?
std::is_empty
是一个特征模板。 std::is_empty<X>
告诉您 type X
是否为空类型——也就是说,它是 struct {}
或 class {}
with 里面什么都没有.
这不是你想要的。首先,因为它不能按照您需要的方式来调用它——它没有对您有用的 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
添加到语言中。
我正在用一些对象填充 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());
我很困惑,谁能告诉我该怎么做?
std::is_empty
是一个特征模板。 std::is_empty<X>
告诉您 type X
是否为空类型——也就是说,它是 struct {}
或 class {}
with 里面什么都没有.
这不是你想要的。首先,因为它不能按照您需要的方式来调用它——它没有对您有用的 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
添加到语言中。