Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This example tries to remove the 3rd item in a container of widgets by using a predicate that returns true only on its 3rd invocation.

Code Block
bgColor#ffcccc
langcpp
class BadPredicate: public unary_function< int, bool> {
public:
  BadPredicate() : timesCalled(0) {}

  bool operator()(const int&) {
    return ++timesCalled == 3;
  }
private:
  size_t timesCalled;
};

int main () {
  vector<int> v;
  for (int i = 0; i < 10; i++) v.push_back(i);

  cout << "Vector contains:";
  for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    cout << " " << *it;
  cout << endl;

  v.erase( remove_if( v.begin(), v.end(), BadPredicate()), v.end());

  cout << "Vector contains:";
  for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    cout << " " << *it;
  cout << endl;

  return 0;
}

...

A simple way to prevent this behavior is to declare the predicate's operator() to be const.

Code Block
bgColor#ffcccc
langcpp
bool operator()(const int&) const {
  return ++timesCalled == 3;
}

...

The proper way to remove a container element based on position is with iterator arithmetic

Code Block
bgColor#ffcccc
langcpp
v.erase( v.begin() + 3);

Risk Assessment

...