我正在使用擦除删除习语:
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? */;
}
并希望返回该方法是否实际删除了任何元素。什么是最干净的方法呢?
答案 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;
}