C ++标准库是否提供更紧凑,更通用的“擦除删除"习惯用法版本? [英] Does C++ standard library provide more compact and generalized version of the erase–remove idiom?

查看:114
本文介绍了C ++标准库是否提供更紧凑,更通用的“擦除删除"习惯用法版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们可以通过流行的擦除–从容器中删除一个元素/条目–删除成语. 但是,在应用此惯用语时,我们许多人会遇到一些问题:

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 不适用于关联 容器 .
  • It even follows the wrong semantics for containers like std::list by not selecting its own member std::list::remove_if() for the idiom.
  • Thirdly, using 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 ,否则

    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

    • For sequence containers like std::vector, std::deque and for std::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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆