Я сталкиваюсь с общей проблемой в моем коде, когда я хотел бы удалить только один элемент из обращенного std :: vector после того, как он удовлетворяет предикату.Я понимаю, что есть несколько способов сделать это с range-v3, но каждый способ, который я придумаю, кажется немного запутанным.
Вот пример целевого вектора v:
std::vector v = { 1, 2, 3, 2, 4 };
Результатом должен быть вектор r:
std::vector r = { 1, 2, 3, 4 };
, что будет сделано путем удаления первых 2 (с помощью лямбда-предиката "is_two"), которыйобнаруживается при обратном обходе вектора v.
Вот один из примеров того, как он может выглядеть в ванильном цикле C ++ raw:
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;
}
}
Вот моя плохая версия range-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, затем удалите элементы в результирующем диапазоне из исходного контейнера.