20

我们可以通过流行的erase-remove idiom从容器中删除一个元素/条目。但是,我们中的许多人在应用这个成语时会遇到一些问题:

  • 人们很容易陷入错别字的陷阱,例如

    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()
  • 第三, usingstd::remove_if 不适用于关联容器

的范围内,我们是否有任何通用且不易出错std::erase-std::remove_if东西,或者在中是否会有这样的实用程序?std::erase_if

4

1 回答 1

30

不在的范围内,而是在以后的范围内!

的。在n4009 论文中提到了一致性容器擦除的提议,并最终在C++20 标准中采用,因为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::erase的序列容器添加了

std::erase(container, value_to_be_removed);
于 2019-07-02T20:16:05.433 回答