Я пытаюсь стереть поддиапазон, возвращаемый find_if ( vec | reverse | slide(width) ) из vector, но все равно не могу добиться соответствия типов их параметров.
Я не уверен, что итератор в этих каналах признан недействительным. Я бы хотел просто использовать существующий итератор поддиапазона, чтобы стереть его, вместо того, чтобы тратить производительность на поиск его снова. Это возможно?
Полный код: Обозреватель компиляторов
Основная функция:
std::vector<Data> take_last_successive_data(std::vector<Data> &target) {
const auto &data_is_successive = [](const auto &data) { return data.is_successive; };
auto windows = target | views::reverse | views::slide(2);
auto result = ranges::find_if (
windows,
[&](const auto &window) {
return ranges::all_of(window | views::take(window.size() - 1), data_is_successive);
}
);
if (result == windows.end()) {
std::cout << "not found\n";
return {};
} else {
// How to erase subrange `result`
target.erase();
auto ret = to_vector(*result | views::reverse);
for (const auto &data : ret) {
std::cout << data.value << ", ";
}
std::cout << '\n';
return ret;
}
}





Сначала разложите subrange, чтобы получить пару reverse_iterator, затем вызовите ее base(), чтобы получить базовый итератор и передать его в erase().
Обратите внимание, что erase() необходимо выполнить после создания ret, чтобы гарантировать, что итератор указывает на действительный элемент.
} else {
auto ret = to_vector(*result | views::reverse);
for (const auto &data : ret) {
std::cout << data.value << ", ";
}
std::cout << '\n';
// How to erase subrange `result`
auto [rbegin, rend] = *result;
target.erase(rend.base(), rbegin.base());
return ret;
}
Здесь очень чисто, и спасибо за заметку, я чуть не пропустил это.