【发布时间】:2021-08-21 23:32:08
【问题描述】:
我有两个向量:
struct MyData{
double value;
};
std::vector<int> remove_flags = {0, 1, 0, 0, 0, 0, 1, 0};
std::vector<MyData> data = {{},{},{},{},{},{},{},{}};
remove_flags 向量包含一个标志数组,其大小与data 完全相同,每个标志为 0 或 1,其中 1 表示应删除数据。
我想使用remove_flags 从data 中删除元素,即执行擦除删除习惯用法,但根据remove_flags 中的值进行擦除。最终结果应该是 data 并删除了元素,希望 remove_flags 删除了相同的元素。
手动执行此操作很烦人,我想为此使用 Range-v3。我目前使用的是 C++17。
查看文档后,我认为我没有找到解决方案,我能想到的最接近的方法是:
auto result = ranges::views::zip(remove_flags, data) | ranges::actions::remove_if([](std::pair<const int&, const MyData&> pair){
return pair.first != 0;
});
remove_flags.erase(result.first, remove_flags.end());
data.erase(result.second, data.end());
但操作无法对视图 zip 进行操作,因此无法编译。如果我将ranges::actions::remove_if 切换为ranges::views::remove_if,则会返回一个奇怪的视图对象,大概是一个实际上没有对两个向量执行std::remove 等效操作的对象。
我可以使用contaner_to,但这会涉及到副本,我不想为了方便而支付这种不必要的罚款。 I've seen what I want accomplished in boost 其中实际的 zip 对迭代器可用于返回两个单独的删除结果。
这种模式在 Range-v3 中是否可行?
【问题讨论】:
-
您是否真的想要
std::vector的结果?风景还不够吗? -
@Enlico 请澄清您的问题,我在帖子中没有提到或演示“结果的标准向量”。事实上,我的例子不可能展示这一点,因为我说
result.first和result.second -
你的 sn-p 的最后两行表明你改变了
data和remove_flags,所以我认为假设你以后想使用 那些 是公平的,即这两个std::vectors 包含您想要实现的“输出/结果/效果”。这就是您在帖子中“提到”您希望代码结果出现在std::vector中的地方(result,而不是result,就像在我的之前的评论)。但是,让我们换一种说法:你的例子不是minimal reproducible example;你能把它变成一个还是用文字描述代码的期望结果/结果/效果是什么? -
@Enlico 上面的例子现在代表一个 MVCE,我已经澄清了我想要的。请注意,标题与我的帖子没有分开,并且 boost 示例(第一部分)有效地给出了我想要的内容,只是没有范围语法。
-
感谢您的澄清。我现在已经删除了我的答案,因为目前这显然不是一个好的答案。目前我没有任何想法。我很想知道为什么你需要移除原位的元素,而仅仅看到它们是不够的。
标签: c++ c++17 range-v3 erase-remove-idiom