STL"擦除 - 删除"成语:为什么不"调整大小 - 删除"?

时间:2014-04-04 10:24:13

标签: c++ stl erase-remove-idiom

众所周知,从std::vector完全删除所需项目的好方法是erase-remove idiom

如上所述链接(截至本帖发布之日)所述,代码中 erase-remove 成语如下所示:

int main()
{
  // initialises a vector that holds the numbers from 0-9.
  std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  // erase-remove idiom to completely eliminate the desired items from the vector
  v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) ); 
}

我想知道resize-remove成语在功能和性能方面是否与erase-remove成语相同。或者,也许我错过了一些明显的东西?

以下resize-remove成语是否等同于上述erase-remove成语?

int main()
{
  std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  // Is this "resize-remove" approach equivalent to the "erase-remove" idiom?
  v.resize( std::remove( std::begin(v), std::end(v), 5 ) - v.begin() ); 
}

4 个答案:

答案 0 :(得分:10)

在我看来,有两个原因:

  1. std::remove算法仅需要Forward Iterator,但- op需要随机访问迭代器。

  2. std::remove的结果意味着“容器的新结束”。从逻辑上讲,我们应该删除[“容器的新端”,“容器的旧端”)。

答案 1 :(得分:5)

它等同于std :: vector,但不适用于std :: list或其他容器。不确定是否可以为std :: list减去迭代器,即使它是,也是O(N)操作。

答案 2 :(得分:2)

它应该没有任何区别; resize以术语定义 inserterase。但通常最好使用 标准成语,以便它可以很容易地被识别。并且 擦除 - 删除成语将适用于任何序列 容器,而不仅仅是那些支持resize的容器。 (所有的 标准容器似乎支持resize,但它 似乎不是一个要求。所以它可能无法使用 在用户定义的容器上,即使它们支持所有容器 必要的操作。)

在性能方面:resize必须额外执行一项 测试,以确定它是擦除还是插入,但是 我无法想象这会产生重大影响。

答案 3 :(得分:1)

我认为erase中的erase(first,last)保证访问或修改first之前没有元素,而resize仅在因调整大小而没有重新分配时保证这一点。< / p>

编辑:正如其他人所指出的那样,这种重新分配永远不会发生,所以没有区别