#include #include #include using namespace std; //----------------------------------------------------------------------- // Example code that creates a container, puts some strings in it, // and then tries to delete them. // Lessons: // (1) Be careful trying to modify a container you're iterating on. // (2) (Very unlike C,) C++ supports full container operations, like // assignment and comparison //----------------------------------------------------------------------- //------------------------------------------------------- // Helper function to print container contents //------------------------------------------------------- template void dumpContainer(const T c) { for (auto &el : c) { cout << el << ' '; } cout << endl; } //------------------------------------------------------- // Copy b to a //------------------------------------------------------- template void reset(T &a, const T &b) { // Container assignment does full contents copy a = b; } //------------------------------------------------------- // mainline //------------------------------------------------------- int main(int argc, char *argv[]) { vector stringVec = {"one", "two", "three", "four"}; cout << "Original vector contents:" << endl; dumpContainer(stringVec); //--------------------------------------------------------- // Create (and preserve) a copy of the container. // Copy constructor makes a deep copy. //--------------------------------------------------------- auto copy = stringVec; // (copy constructor invocation) //-------------------------------------------------------------------------- // Note that the equality operator here actually compares container contents //-------------------------------------------------------------------------- cout << "copy == stringVec? " << (copy == stringVec ? "yes" : "no") << endl; cout << endl << "Now try to erase all elements that begin with 't':" << endl; //--------------------------------------------------------------- // Modifying a container you're iterating on is risky -- sometimes // it's okay, and sometimes it's a fatal error. //--------------------------------------------------------------- //--------------------------- // 1st try - naive approach //--------------------------- for ( auto it = stringVec.begin(); it != stringVec.end(); it++ ) { if ( (*it)[0] == 't' ) stringVec.erase(it); } cout << setw(20) << "First try result: "; dumpContainer(stringVec); //--------------------------- // 2nd try - use updated iterator returned by erase() //--------------------------- reset(stringVec, copy); for ( auto it = stringVec.begin(); it != stringVec.end(); it++ ) { if ( (*it)[0] == 't' ) it = stringVec.erase(it); } cout << setw(20) << "Second try result: "; dumpContainer(stringVec); //--------------------------- // 3rd try - correct! //--------------------------- reset(stringVec, copy); auto it = stringVec.begin(); while ( it != stringVec.end() ) { if ( (*it)[0] == 't' ) it = stringVec.erase(it); else it++; } cout << setw(20) << "Third try result: "; dumpContainer(stringVec); return 0; }