在range-v3的zip视图中实现修改底层容器的drop操作可行吗?
解决方案:安全地对多个容器执行同步drop操作
range-v3 并没有提供直接对 zip_view 执行修改类 action(如 actions::drop)的组件,因为 zip_view 是视图类的 range,仅负责组合多个容器的元素,无法直接映射到底层容器的修改操作。但我们可以通过封装自定义逻辑,实现同步修改多个容器并保证操作一致性的需求。
1. 基础实现:同步删除相同数量的元素
如果核心需求是让两个容器删除相同数量的元素(避免手动调用两次 actions::drop 的繁琐,同时保证删除数量一致),可以封装一个通用函数:
#include <range/v3/action/drop.hpp> #include <range/v3/range/access.hpp> #include <fmt/ranges.h> #include <vector> #include <algorithm> template <typename Range1, typename Range2> void drop_zip(Range1& r1, Range2& r2, std::size_t drop_count) { // 计算实际能安全删除的数量:取要删除的数量与两个容器中较小长度的最小值 // 确保两个容器都能删除这么多元素,不会出现单个容器元素不足的情况 const auto actual_drop = std::min(drop_count, std::min(ranges::size(r1), ranges::size(r2))); ranges::actions::drop(r1, actual_drop); ranges::actions::drop(r2, actual_drop); } // 使用示例 void drop_zip_vec_vec() { std::vector v {1,2,3,4,5}; std::vector v2 {2,3,4,5,6}; drop_zip(v, v2, 3); fmt::print("v: {} \nv2: {} \n", v, v2); // 输出 v: [4,5],v2: [5,6] // 测试长度不一致的场景 std::vector v_short {1,2,3}; std::vector v_long {1,2,3,4,5,6}; drop_zip(v_short, v_long, 4); fmt::print("v_short: {} \nv_long: {} \n", v_short, v_long); // 都删除3个,v_short空,v_long剩[4,5,6] }
2. 进阶实现:保证剩余容器长度一致
如果需求是操作后两个容器的剩余长度相同(而非删除数量相同),可以调整逻辑,先计算最终应保留的长度,再对每个容器执行对应删除:
template <typename Range1, typename Range2> void drop_zip_keep_same_length(Range1& r1, Range2& r2, std::size_t drop_count) { const auto len1 = ranges::size(r1); const auto len2 = ranges::size(r2); // 计算最终应保留的长度:取两个容器原长减drop_count后的最大值与0的较大值 const auto target_remain = static_cast<std::size_t>( std::max(0LL, std::min(static_cast<long long>(len1), static_cast<long long>(len2)) - static_cast<long long>(drop_count)) ); // 对每个容器删除到目标剩余长度 if (len1 > target_remain) { ranges::actions::drop(r1, len1 - target_remain); } if (len2 > target_remain) { ranges::actions::drop(r2, len2 - target_remain); } } // 使用示例 void drop_zip_vec_vec_same_length() { std::vector v {1,2,3,4,5}; std::vector v2 {2,3,4}; drop_zip_keep_same_length(v, v2, 4); fmt::print("v: {} \nv2: {} \n", v, v2); // 都为空,因为min(5,3)-4 = -1 → 保留0个 }
为什么不能直接用zip_view执行action?
views::zip 生成的是视图,仅将多个range的元素按位置组合,没有自身的底层存储结构。range-v3的action(如 actions::drop)需要作用于拥有自身存储的可修改容器,视图无法满足这一要求,因此无法直接通过zip视图同步修改多个底层容器。
内容的提问来源于stack exchange,提问作者NoSenseEtAl
相关产品推荐
相关产品推荐

