【问题标题】:C++11: erase-remove idiom when searching a specific member of object within a vectorC ++ 11:在向量中搜索对象的特定成员时擦除删除习语
【发布时间】:2016-11-23 13:18:09
【问题描述】:

我知道erase-remove可以用来删除匹配某个值的元素,像这样:

v.erase(std::remove(v.begin(), v.end(), value), v.end());

但是,如果我的向量有对象并且我只需要删除其中一个变量与特定值匹配的对象,那么擦除删除是否可能? 到目前为止,我一直在使用:

auto i = vect.begin();
while (i!=vect.end())
   if ((*i).field==someValue)
        i=vect.erase(i);
   else
      ++i;

有没有办法对擦除删除做同样的事情,或者这个 while 循环是正确的选择?

【问题讨论】:

标签: c++11 erase


【解决方案1】:

您可以使用标准算法std::remove_if 而不是std::remove

【讨论】:

  • 我明白了!那会比我的while循环更安全还是更好,或者我可以根据自己的喜好使用其中一种?谢谢。
  • 一般来说使用标准算法比手动编码要清晰一点。例如,在您的代码中,您正在修改vector,同时对其进行迭代;这将在运行时导致问题。标准算法已经可以处理这个和其他“常见”问题,所以最好尽可能多地使用它们。
  • 原来的while循环是正确的。然而主要的缺点是每次删除一个元素时,向量中的所有后续元素都会移动(这需要std::distance(it_to_removed_element, end) 移动)。但是,std::remove_if/std::remove 使用巧妙的交换来避免不必要的移动。
【解决方案2】:

我避免直接​​写erase-remove,主要是因为如果你错过了最后的container.end(),就会发生非常糟糕的事情。

template<class C, class T>
void erase_remove( C& c, T&& t ) {
  using std::begin; using std::end;
  auto it = std::remove(begin(c), end(c), std::forward<T>(t));
  c.erase(it, end(c));
}
template<class C, class F>
void erase_remove_if( C& c, F&& f ) {
  using std::begin; using std::end;
  auto it = std::remove_if(begin(c), end(c), std::forward<F>(f));
  c.erase(it, end(c));
}

然后将一个用于测试f 参数的成员变量的lambda 传递给erase_remove_if

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多