2015-06-10 2 views
0

Я использую стирающие удалить идиомы:erase-remove idiom: я просто что-то удалял?

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; 
    } 
} 
+0

Этот, кажется, максимально использует библиотеку, спасибо! – PhilLab

4

Я бы просто проверил размер вектора. Что-то вроде:

auto size_before = v.size(); 
// v.erase(...) 
return v.size() != size_before; 
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()); 
} 
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; 
} 
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 везде, если вы обнаружите влияние производительности.