删除for-range循环中项目的最快方法
The quickest method to delete items inside for - range loop
我在想这个循环:
struct tmp {
int min;
int max;
tmp(int a, int b) :min(a), max(b){};
};
std::vector <tmp> data;
for (auto tmp_a : data){
if(tmp_a.min == 0){
//how to delete tmp_a item from data from there?
}
}
当然,我可以迭代这个循环,但我不认为这是最快的方法。(当然我可能错了——那就纠正我吧)
问题:如何删除范围循环内的项目(使用最快的方法)
忘记循环并使用擦除-删除习惯用法。
data.erase(std::remove_if(data.begin(), data.end(), [] (tmp t) {
return t.min == 0;
}), data.end());
template<class C, class F>
void remove_erase_if( C& c, F&& f ) {
using std::begin; using std::end;
c.erase( std::remove_if( begin(c), end(c), std::forward<F>(f) ), end(c) );
}
这是一种采用容器CCD_ 1和测试函数CCD_。它删除了所有通过测试f
的元素。
我发现这样把它捆绑在一起可以减少我忘记,end(c)
组件的机会,而且这两个操作(删除然后擦除)经常联系在一起,使它们成为一个操作来清理调用代码。
我们接受您的代码:
for (auto tmp_a : data){
if(tmp_a.min == 0){
//how to delete tmp_a item from data from there?
}
}
并替换控制回路:
remove_erase_if( data, [&](tmp const& tmp_a){
return (tmp_a.min == 0);
});
或在C++14:中
remove_erase_if( data, [&](auto&& tmp_a){
return (tmp_a.min == 0);
});
其中,如果我们从lambda返回true
,则元素将从容器中移除,如果我们返回false
,则保留该元素。
虽然采用tmp&
将进行编译,但修改tmp_a
在技术上是未定义的行为。我认为这是对标准的过分规范。但是,如果您需要迭代和修改,则需要编写自己版本的remove_if
:最简单的实现在修改和/或擦除元素方面没有问题。
template<class It, class F>
It my_remove_if( It start, It end, F f ) {
It target = start;
for(It& it = start; it != end; ++it) {
if (f(*it))
continue;
if (it != target)
*target = std::move(*it);
++target;
}
return target;
}
它与c
0接口匹配(我更喜欢使用F&&
,但兼容性很重要),除了它明确允许在删除元素的同时修改容器的内容之外,它也做了同样的事情。
另一种可能性是使用以下内容:
auto iter = data.begin();
while( iter != data.end() ) {
if( iter->min == 0 )
iter = data.erase(iter);
else
++iter;
}
适用于所有容器(包括自c++11以来的关联容器),这也是erase
返回迭代器的原因。如果它在clearly express intent
中与擦除删除相比是好是坏,这是一个有争议的话题,我个人更喜欢它。
请注意,对于连续容器(如vector
),每个erase
都将移动它之后的所有项,这可能非常低效,尤其是在目标硬件没有预取功能,或者值类型不支持移动语义的情况下。
相关文章:
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 在Visual Studio C++项目中包含源库的正确方法是什么?
- 实现Eigen's块或Boost's的项目方法
- Visual Studio 2015资源视图和资源编译器使用不同的方法在项目目录中查找图标文件.如何修复
- 有没有一种简单的方法可以在C++中获取特定索引之后向量中的所有项目?
- 是否可以简化此方法以安装和导出基于 CMake 的项目?
- 有没有更好的方法来检测向量中一个项目的多次出现?
- 是否有其他方法将.dll文件从一个项目复制到我的启动项目中的可执行文件旁边
- 我有一个启用了代理存根支持的 ATL 项目,在哪里可以找到 xdlldata.h 文件中所有方法的实现
- C++简单的暴力项目密码输入方法
- Winforms-将Visual C 项目UI转换为Visual C#的任何方法
- (C )正在创建专门用于处理所有其他自定义对象的类/对象一种处理项目的正确方法
- 从多个 std::vector 中删除项目的最快方法
- 使用VCPKG与朋友共享您的项目的最佳方法是什么?
- 使用C 支持创建Android项目的正确方法
- 在C 开源项目中包括单位测试的最佳方法
- 测试项目在访问私有静态方法时遇到问题,尽管我从未直接调用过它
- 这是从VS window c ++项目迁移到linux项目的最有效方法
- Qt项目中对glew方法的未定义引用
- 消除QGraphics生成的"unused parameter 'widget'"警告的干净方法项目::p aint