c++ - 使用其范围版本从容器中删除元素的最佳方法
问题描述
我在我的代码中遇到一个常见问题,我想在它满足谓词后从反转的 std::vector 中只删除一个元素。我知道使用 range-v3 有很多方法可以做到这一点,但我想出的每一种方法似乎都有些复杂。
这是目标向量 v 的示例:
std::vector v = { 1, 2, 3, 2, 4 };
结果需要是向量 r:
std::vector r = { 1, 2, 3, 4 };
这将通过删除反向遍历向量 v 时找到的前 2 个(通过 lambda 谓词“is_two”)来完成。
这是在普通 C++ 原始循环中的样子:
auto is_two = [](int a) { return a == 2; };
for (int i = v.size(); --i >= 0;) {
if (is_two(v[i])) {
v.erase(v.begin() + i);
break;
}
}
这是我的坏范围-v3 版本:
namespace rs = ranges;
namespace rv = ranges::view;
namespace ra = ranges::action;
rs::for_each(v | rv::enumerate
| rv::reverse
| rv::filter([](auto i_e) { return i_e.second == 2; })
| rv::take(1),
[&](auto& i_e) { v.erase(v.begin() + i_e.first); });
理想情况下,我想知道是否有一些看起来像这样的解决方案:
ra::remove_if(v | rv::reverse, is_two);
概括地说,我想知道如何获取一个容器,通过一些 range::view 操作对其进行管道传输,然后从原始容器中删除结果范围内的元素。
解决方案
由于似乎没有人想出更好的方法,为了您的利益,我想提一下使用 good old reverse_iterator
s 的可能性。
vec.erase(std::prev(ranges::find_if(vec.rbegin(), vec.rend(), is_two).base()));
诚然,这不是很范围,但至少它有效。
推荐阅读
- javascript - 合并 2 个数组示例 [a,b,c] [x,y,z] = [a,x,b,y,c,z]
- python - GPflow分类:后验方差的解释
- sql - 如何更新 SQL Server 中的记录,但只能使用参数中的非空值?
- r - 尝试使用 rvest 进行网络抓取时如何修复“UseMethod("xml_find_all") 中的错误”
- python - 版本 Gmsh(版本 >=2)和 Fipy 的问题
- html - AHK 无法加载所有 html
- c# - 为什么类型推断在这种情况下不起作用?
- vue.js - 使用了Html2canvas截图,但是截图和原图差别很大
- mysql - 如何通过 Laravel 迁移为每一行触发 MySQL 过程
- angular - 如何转到指定的 URL?