I've got two vectors:
struct MyData{
double value;
};
std::vector<int> remove_flags = {0, 1, 0, 0, 0, 0, 1, 0};
std::vector<MyData> data = {{},{},{},{},{},{},{},{}};
The remove_flags
vector contains an array of flags of the exact same size as data
, each flag is either 0, or 1, where 1 means the data should be removed.
I would like to use remove_flags
to remove elements from data
in place, ie performing the erase remove idiom, but erasing based on values in remove_flags
. The end result should be data
with elements erased, and hopefully remove_flags
with those same elements erased.
Doing this manually is annoying, and I wanted to use Range-v3 for this. I'm currently using C++17.
After looking through the documentation, I don't think I've found a solution, the closest thing I could come up with is:
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());
But actions cannot operate on the view zip, so this does not compile. If I switch ranges::actions::remove_if
to ranges::views::remove_if
a strange views object is returned, presumably one that has not actually performed the std::remove
equivalent operation on the two vectors.
I could use contaner_to
but that would involve a copy, and I don't want to pay that kind of unnecessary penalty for convenience. I've seen what I want accomplished in boost where actual zip pair iterators can be used to return two separate removal results.
Is this kind of pattern possible in Range-v3?