STL issues



// iterator invalidation

std::list<int> n;

// remove negatives ...
for( std::list<int>::iterator i = n.begin(); i != n.end(); ++i )
{
  if ( 0 > *i )
  {
    n.erase( i );
  }
}



for( std::list<int>::iterator i = n.begin(); i != n.end(); )
{
  std::list<int>::iterator curr = i++;
  if ( 0 > *curr )
  {
    n.erase( curr );
  }
}



// vector allocation

const int N = 1000;


vector<int> v;

for(int i = 0; i < N; ++i)
{
  v.push_back( i );
}


// with reserve

vector<int> v;
v.reserve( N );

for(int i = 0; i < N; ++i)
{
  v.push_back( i );
}



// decreasing vector capacity

for(int i = 0; i < N-10; ++i)
{
  v.pop_back();
}

// still ~1024 reserved




// the swap-trick:

vector<int>( v ).swap( v );  // v has no minimal required capacity


// works for std::string too:

string s;
//...

string( s ).swap( s );



// vector bool is not vector
//
// fully specialized, not storing bool type objects

vector<bool> v;
//...

bool* p = &v[0]; // ???  v[i] returns a proxy class object




// reverse iterator
//

Container<T> c;
...
Container<T>::reverse_iterator ri = ...


c.erase( --ri.base() );  // sometimes syntax error: --(ri.base())


c.erase( (--ri).base() );




// special iterators:


// input-output iterators:
copy( istreambuf_iterator<char>( cin ),
      istreambuf_iterator<char>(),
      ostreambuf_iterator<char>( cout ) );



// predicates

template <typename FwdIterator, typename Predicate>
FwdIterator remove_if( FwdIterator begin,
                       FwdIterator end,
                       Predicate p )
{
  begin = find_if( begin, end, p );
  if ( begin == end ) return begin;
  else
  {
    FwdIterator next = begin;
    return remove_copy_if( ++next, end, begin, p );
  }
}



// algorithm pitfalls


vector<int>  vi;

for( int i = 0; i < 10; ++i )  vi.puch_back(i);


remove( vi.begin(), vi.end(), 5);  // how many elements in vi ?




vector<int>::iterator i = remove( vi.begin(), vi.end(), 5);

vi.erase(i,vi.end());




list<int>  li;

//...

li.remove(5);




vector<int>::iterator i = vi.unique( vi.begin(), vi.end() );