擦除 - 删除成语:我刚刚删除了什么?

时间:2015-06-10 07:13:49

标签: c++ std stdvector

我正在使用擦除删除习语:

template <typename T>
bool garbageCollectVector(std::vector<T>& v) {
    // Use the erase-remove idiom in combination with a lambda expression
    v.erase(
        std::remove_if(v.begin(), v.end(),
            [this](const T& elem) -> bool {
                return this->shouldRemove(elem);
            }
        ),
        v.end());
    return /* what to return? */;
}

并希望返回该方法是否实际删除了任何元素。什么是最干净的方法呢?

5 个答案:

答案 0 :(得分:5)

除尺寸检查外,您可以拆分实施:

template <typename T>
bool garbageCollectVector(std::vector<T>& v) {
    // Use the erase-remove idiom in combination with a lambda expression
    auto it = std::remove_if(v.begin(), v.end(),
                             [this](const T& elem) -> bool {
                                return this->shouldRemove(elem);
                             });
    if (it == v.end()) {
        return false;
    } else {
        v.erase(it, v.end());
        return true;
    }
}

答案 1 :(得分:4)

我只是检查矢量的大小。类似的东西:

auto size_before = v.size();
// v.erase( ... )
return v.size() != size_before;

答案 2 :(得分:1)

template<class C, class F>
bool 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));
  if (it==end(c)) return false;
  c.erase(it, end(c));
  return true;
}

这将成语变成了一个函数。

template <typename T>
bool garbageCollectVector(std::vector<T>& v) {
  // Use the erase-remove idiom in combination with a lambda expression
  return erase_remove_if(v,
    [this](const T& elem) -> bool {
      return this->shouldRemove(elem);
    }
  );
}

保持每行的复杂性。

如果发现性能影响,您可以调整哪个(跟踪bool或迭代器检查)更快,并在任何地方更改erase_remove_if

答案 3 :(得分:0)

怎么样:

template <typename T>
bool garbageCollectVector(std::vector<T>& v) {
    auto prevSize = v.size();
    // Use the erase-remove idiom in combination with a lambda expression
    v.erase(
        std::remove_if(v.begin(), v.end(),
            [this](const T& elem) -> bool {
                return this->shouldRemove(elem);
            }
        ),
        v.end());
    return !(prevSize == v.size());
}

答案 4 :(得分:0)

其他人提出了更好的替代方案,但让我加以说明这一点。它使用一个标志来检查谓词是否返回true。

template <typename T>
bool garbageCollectVector(std::vector<T>& v) {
    // Use the erase-remove idiom in combination with a lambda expression
    bool removed = false;
    v.erase(
        std::remove_if(v.begin(), v.end(),
            [this,&removed](const T& elem) -> bool {
                bool to_remove = this->shouldRemove(elem);
                removed = removed || to_remove;
                return to_remove;
            }
        ),
        v.end());
    return removed;
}