Ответ 1
Не в рамках c++17, но c++20 и далее!
Да Предложение согласованного удаления контейнеров было упомянуто в статье n4009 и, наконец, принято в стандарте С++ 20 как std::erase_if
который является std::erase_if
являющейся членом каждого контейнера.
Это обеспечивает единообразную семантику стирания контейнеров для std::basic_string
и всех стандартных контейнеров, кроме std::array
(так как он имеет фиксированный размер).
Это означает, что стандартный код
container.erase(
std::remove_if(
container.begin(), container.end(),
[](const auto& element) ->bool { return /* condition */; }),
vec.end());
просто расплавится до обобщенной формы
std::erase_if(container, [](const auto& element) ->bool { return /* condition */; });
Во-вторых, этот унифицированный синтаксис выбирает правильную семантику для каждого контейнера. Это означает
-
Для контейнеров последовательностей, таких как
std::vector
,std::deque
и дляstd::std::basic_string
, это будет эквивалентноcontainer.erase( std::remove_if(container.begin(), container.end(), unaryPredicate) , container.end() );
-
Для контейнеров последовательностей
std::forward_list
иstd::list
это будет эквивалентноcontainer.remove_if(unaryPredicate);
-
Для упорядоченных ассоциативных контейнеров (например,
std::set
,std::map
,std::multiset
иstd::multimap
) и неупорядоченных ассоциативных контейнеров (т.е.std::unordered_set
,std::unordered_map
,std::unordered_multiset
иstd::unordered_multimap
),std::erase_if
эквивалентноfor (auto i = container.begin(), last = container.end(); i != last; ) { if (unaryPredicate(*i)) { i = container.erase(i); } else { ++i; } }
В дополнение к этому стандарт также добавил std::erase
для контейнеров последовательностей вида
std::erase(container, value_to_be_removed);