C ++标准库是否提供更紧凑,更通用的“擦除删除"习惯用法版本? [英] Does C++ standard library provide more compact and generalized version of the erase–remove idiom?
问题描述
我们可以通过流行的擦除–从容器中删除一个元素/条目–删除成语. 但是,在应用此惯用语时,我们许多人会遇到一些问题:
We can erase one element/ entry from a container by the popular erase–remove idiom. However, many of us would have encountered some problems while applying this idiom:
-
一个人很容易陷入 typos 之类的陷阱
c.erase(std::remove_if(c.begin(), c.end(), pred));
// , c.end() //---> missing here
或
c.erase((std::remove_if(c.begin(), c.end(), pred), c.end()))
// ^^ ^^
// extra () makes it pass only c.end() to the c.erase
std::list
通过不选择其自己的成员
std::list::remove_if()
为成语.std::remove_if
不适用于关联
容器 .
std::list
by not selecting its own member
std::list::remove_if()
for the idiom.std::remove_if
does not work for associative
containers. 在std::erase-std::remove_if或std::erase_if
之类的更通用且更不易错字的内容? class ="post-tag" title =显示标记为'c ++ 17'"的问题rel ="tag"> c ++ 17 ,否则 c ++ 20 ?
Do we have anything generalized and less typo-prone than std::erase-std::remove_if
or something like std::erase_if
within the scope of c++17, or will there be such a utility in c++20?
推荐答案
不在 c ++ 17 ,但 n4009论文中提到了容器一致性擦除的建议,并最终在 C ++ 20标准为 std::erase_if
每个容器的非成员功能.
Not in the scope of c++17, but c++20 onwards!
Yes. The proposal of consistent container erasure has been mentioned in n4009 paper and finally adopted in C++20 standard as std::erase_if
which is a non-member function for each containers.
这确保了std::basic_string
和所有标准容器的统一容器擦除语义,除了std::array
(因为它具有固定大小).
This ensures a uniform container erasure semantics for std::basic_string
and all standard containers, except std::array
(as it has the fixed-size).
这意味着样板代码
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 */; });
第二,此统一语法为每个容器选择正确的语义.这意味着
Secondly, this uniform syntax selects the proper semantics for each container. This means
-
对于诸如
std::vector
,std::deque
并用于std::std::basic_string
,它等效于
For sequence containers like
std::vector
,std::deque
and forstd::std::basic_string
, it will be equivalent to
container.erase(
std::remove_if(container.begin(), container.end(), unaryPredicate)
, container.end()
);
对于序列容器 std::forward_list
和 std::list
,
等同于
For sequence containers std::forward_list
and std::list
, it will
be equivalent to
container.remove_if(unaryPredicate);
对于有序关联容器(即 std::set
, std::map
,
std::multiset
和 std::unordered_set
, std::unordered_multiset
和
For ordered associative containers(i.e. std::set
, std::map
,
std::multiset
and std::multimap
) and unordered associative
containers(i.e. std::unordered_set
, std::unordered_map
,
std::unordered_multiset
and std::unordered_multimap
), the
std::erase_if
is equivalent to
for (auto i = container.begin(), last = container.end(); i != last; )
{
if (unaryPredicate(*i))
{
i = container.erase(i);
}
else
{
++i;
}
}
除此之外,该标准还为表单的序列容器添加了 std::erase
In addition to that, the standard also added std::erase
for sequence containers of the form
std::erase(container, value_to_be_removed);
这篇关于C ++标准库是否提供更紧凑,更通用的“擦除删除"习惯用法版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!