不使用std::erase时std::remove_if的用例

3
考虑这段简单的代码,它从一个 int 向量中移除小于或等于 6 的值。
int main(void) {
  std::vector<int> v{ 1,3,6,7,8,9 };

  auto x = v.erase(std::remove_if(v.begin(), v.end(), [](auto x) {return x <= 6; }), v.end());

  for (auto & value : v)
    std::cout << value << "\n";
}

这段代码运行良好,但我想知道在不从向量的末尾删除剩余的“无效”元素的情况下使用std::remove_if的用例是什么。


2
据我所知,目前没有这样的函数。如果您想将某些元素移动到前面并且不关心其余元素的顺序,请使用 std::partition。我认为,如果您使用 std::remove_if 来不删除元素,则是在欺骗阅读代码的人。 - NathanOliver
@NathanOliver-ReinstateMonica 说谎的部分正是我的想法。 - Jabberwocky
1
使用std::remove_if而不从向量末尾删除其余的“无效”元素的用例是什么?请记住,std::remove_if可用于常规数组,您无法删除其中的元素。 - PaulMcKenzie
1
附加说明:您还可以使用ranges-v3/ranges TS/C++20中的filter_view,在仍然能够使用基于范围的for循环的同时,零成本地移动/复制任何内容。 - NathanOliver
1
与分区不同的是,尾部元素不会保留已删除元素的值。因此,如果它们没有被擦除,它们将包含(有效地)垃圾值。 - Eljay
1个回答

6
您可能正在使用例如 std::array 的数据结构。其中的元素不能被删除,但您可以使用 std::remove_if 来将“已删除”的元素划分到末尾(比喻性地),并使用指针指定最后一个“有效”的元素(或者是它的下一个元素),并可能销毁已删除的元素。
抽象而言,这仍然是“删除”,因此我想我的观点是,在您使用的数据结构中可能没有预先存在的删除功能。因此,我必须得出结论:在“删除”之后,我无法想到任何有意义的用例不使用某种形式的删除。
请注意,std::partition 虽然类似,但不是相同的算法。它更加耗费资源,因为它需要保持两个部分的元素不变。std::remove_if 可以覆盖已删除的元素。实际上,它可以使用单一移动操作,而 std::partition 需要进行交换。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接