STL Containers Last update: 3/30/2003 Copyright Kip Irvine, 2003. All rights reserved. Only students enrolled in a class at Florida International University may copy or print the contents of this slide show. 1 Standard Template Library (STL) Created by Alexander Stepanov and Meng Lee at Hewlett-Packard Key components: containers, iterators, algorithms Helps you avoid having to re-invent standard container implementation code Design choice: generic classes chosen for runtime efficiency • more efficient than object-based containers that use polymorphism Copyright 2003, Kip R.Irvine 2 Standard Template Library (STL) Recently incorporated into the Standard C++ Library STL Programmers' Guide available at: • http://www.sgi.com/tech/stl • Latest release: 3.3, June 2000. Copyright 2003, Kip R.Irvine 3 Types of Containers Sequence containers • vector • deque • list Associative containers • set, multiset • map, multimap Container adapters • stack • queue • priority_queue Copyright 2003, Kip R.Irvine 4 Required Headers Class name same as header: • <vector>, <list>, <deque>, <stack>, <bitset> Also: • <queue> • <set> • <map> queue, priority_queue set, multiset map, multimap Copyright 2003, Kip R.Irvine 5 Error Handling Exceptions are never thrown by STL classes In fact, exceptions and templates don't mix Very little error checking exists in STL classes Copyright 2003, Kip R.Irvine 6 Common Typedefs value_type • type of element stored in the container reference, const_reference • reference to type of element stored in the container pointer • pointer to the type of element stored in the container iterator, const_iterator • a forward iterator that points to the type of element stored in the container reverse_iterator, const_reverse_iterator • a reverse iterator that points to the type of element stored in the container Copyright 2003, Kip R.Irvine 7 Common typedefs in STL (cont) difference_type • type of the result of subtracting two iterators size_type • type used to count items in a container, and index through a sequence container Copyright 2003, Kip R.Irvine 8 Common Member Functions default constructor, copy constructor, destructor empty max_size • max number of elements for a container size • number of elements currently in the container operator = • assign one container to another overloaded <, <=, >, >=, ==, != swap Copyright 2003, Kip R.Irvine 9 Common Member Functions begin end erase clear rbegin rend returns an iterator (-> first element) returns an iterator (-> after last element) erase 1 or more elements erase all elements returns reverse_iterator returns reverse_iterator Copyright 2003, Kip R.Irvine 10 Element Types for Containers Must have correct copy semantics • bitwise default, or • overload the assignment ( = ) operator and copy constructor Provide operator < and operator == Copyright 2003, Kip R.Irvine 11 Types of Iterators Input Iterator (InIt) • Used to read an element from a container • Moves only in forward direction, one element at a time • Cannot pass through a sequence twice Output Iterator (OutIt) • Used to write an element to a container • Moves only in forward direction, one element at a time • Cannot pass through a sequence twice Each iterator's capabilities are a superset of the previously listed iterators. Copyright 2003, Kip R.Irvine 12 Types of Iterators (cont) Forward Iterator (FwdIt) • reads and writes in forward direction only • retains its position in the container Bidirectional Iterator (BidIt) • reads and writes in both directions • retains its position in the container Random-Access Iterator (RadIt) • reads and writes in randomly accessed positions • permits pointer arithmetic Each iterator's capabilities are a superset of the previously listed iterators. Copyright 2003, Kip R.Irvine 13 Iterator Support, by Container stack, queue, priority_queue: list, set, multiset, map, multimap: vector, deque: Copyright 2003, Kip R.Irvine no iterators bidirectional random 14 Invalidating Iterators Some, but not all operations on containers invalidate iterators • result: iterator can be stale • remember that iterators are basically pointers Examples: • list.push_back( ) does not invalidate iterators • vector.push_back( ) invalidates all iterators • list.erase( ) invalidates only iterators that pointed to the deleted elements • check the documentation for each method! Copyright 2003, Kip R.Irvine 15 Sequence Containers Copyright 2003, Kip R.Irvine 16 vector Container sequence container with contiguous memory locations permits direct access to any member via [ ] or at( ) automatically doubles its allocation when current size is exceeded insertion and deletion only permitted at the tail supports random-access iterators • all lesser iterators also Copyright 2003, Kip R.Irvine 17 Common vector Functions push_back, pop_back • add to end, remove from end size • current number of elements capacity • storage allocation size begin, end • return iterator and const_iterator rbegin, rend • return reverse_iterator and const_reverse_iterator front, back • return first and last elements Copyright 2003, Kip R.Irvine 18 Common vector Functions at( ) operator [ ] (also found in deque) Copyright 2003, Kip R.Irvine 19 list Sequence Container efficient insertion and deletion at any location • deque is more efficient if insertions and deletions are at the ends of the container implemented as doubly-linked list • supports bidirectional iterators does not support • at( ) or operator [ ] Copyright 2003, Kip R.Irvine 20 list Operations operations not found in vectors: void splice( iterator iter, list & X ) • removes values from list X and inserts them into the current list in the position immediately before position iter void push_front( const T & X ) • inserts element X at the front of the list void pop_front( ) • removes one element from the front of the list void remove( const T& x ) • removes all elements found to be equal to X Copyright 2003, Kip R.Irvine 21 Unique list Operations void unique() Removes from the current list every element that is equal to its preceding element void merge( list & other ) Removes from the list other and insert them in sorted order into the current list void reverse() Reverses the order of elements in the current list void sort() Sorts the list in ascending order by automatically calling the < operator function to compare pairs of elements void sort( greater<T> pred ) Sorts the list in descending order by automatically calling the < operator function to compare pairs of elements Copyright 2003, Kip R.Irvine 22 Creating a list list<int> scores; scores.push_back( 20 ); scores.push_front( 10 ); scores.pop_front( ); scores.remove( 20 ); // removes "20" cout << "size: " << scores.size( ) << endl; List of lists containing strings: list< list<string> > L; Disable Microsoft VS 6.0 warning message that appears when templates contain strings: #ifdef _DEBUG #pragma warning( disable : 4786 ) #endif Copyright 2003, Kip R.Irvine 23 Printing a list template < class T > void print( const list<T> & aList ) { if ( aList.empty() ) cout << "List is empty"; else { list<T>::const_iterator I = aList.begin( ); for( ; I != aList.end( ); I++ ) cout << *I << ", "; cout << endl; } } Copyright 2003, Kip R.Irvine 24 Removing list Duplicates list<int> scores; scores.push_back( scores.push_back( scores.push_back( scores.push_back( scores.unique( ); print( scores ); 10 20 30 30 ); ); ); ); // 10, 20, 30 Copyright 2003, Kip R.Irvine 25 List of Lists typedef list<string> stringList; stringList s; s.push_back( "Dan" ); s.push_back( "Bill" ); s.push_back( "Anne" ); // a list containing lists of strings list<stringList> L; L.push_back( s ); Copyright 2003, Kip R.Irvine 26 Associative Containers Copyright 2003, Kip R.Irvine 27 Associative Containers keys are always kept in sorted order • iterator always traverses in sort order set – single key values • equivalent to Java's TreeSet multiset – duplicate keys allowed map – contains pairs (key, value) • key is unique • equivalent to Java's TreeMap multimap • key need not be unique Copyright 2003, Kip R.Irvine 28 Sets: Three Ways to Insert Items insert single value, returning an iterator iterator insert( const value_type & x); start searching for insert point after iterator it: iterator insert( iterator it, const value_type & x ); insert sequence of elements in the range [first, last): void insert( const value_type * first, const value_type * last ); Copyright 2003, Kip R.Irvine 29 Examples: Inserting and Finding Create a multiset and insert single values: multiset<int> B; B.insert( 30 ); B.insert( 20 ); Insert an array: const int SIZE = 5; int array1[SIZE] = { 10,20,30,30,40 }; B.insert( array1, array1 + SIZE ); Find a value: multiset<int>::const_iterator I = B.find( 30 ); Copyright 2003, Kip R.Irvine 30 Using typedef Use typedef to simplify type definitions: typedef multiset<int> msetInt; . msetInt A; typedef multiset<int>::const_iterator msetIter; . msetIter = A.insert( 30 ); Copyright 2003, Kip R.Irvine 31 Printing a Multiset template < class T > void print( const multiset<T> & aSet ) { if ( aSet.empty() ) cout << "Set is empty"; else { multiset<T>::const_iterator I = aSet.begin( ); for( ; I != aSet.end( ); I++ ) cout << *I << ", "; } } Copyright 2003, Kip R.Irvine 32 set Associative Container keys are unique • attempt to insert duplicate key is ignored same functions as multiset Copyright 2003, Kip R.Irvine 33 map Associative Container unique keys and their associated values each key is mapped to a single value • values do not have to be unique fast storage and retrieval sorted in order according to keys Iterators point to pair<key,value> • fields named first, second values can be inserted using [ ] operator see: mapdemo.cpp Copyright 2003, Kip R.Irvine 34 Function Objects template class that contains a function • the function can be used in the same way as operator ( ) make STL more flexible • permit sorting on your own criteria predefined objects in STL: • • • • • • divides< T > equal_to< T > greater< T > greater_equal< T > less< T > etc. Copyright 2003, Kip R.Irvine 35 Function Object Example Default comparison of STL container objects when sorting uses the < operator: template<typename T> class less { public: bool operator()(const T & x, const T & y) const { return x < y; } }; Copyright 2003, Kip R.Irvine 36 Function Object Example When you declare a set, you have the option of specifying a function object that will determine the positions where new elements are inserted. Example: set of strings named myStringSet: set<string, less<string> > myStringSet; Copyright 2003, Kip R.Irvine 37 Binary Function Example Base class binary_function defines overloaded ( ) operator with two arguments. This function object squares a value and adds it to a total: template< typename T > class SumSquaresClass :public binary_function<T, T, T> { public: const T operator( )( const T & total, const T & value ) { return total + value * value; } }; Copyright 2003, Kip R.Irvine 38 Binary Function Example (cont) accumulate( first, last, startVal, pred ) The STL defines an accumulate function that accumulates a sum over a collection. • the optional pred parameter can be a function or a function object vector<int> v; . . . int sum = accumulate( v.begin( ), v.end( ), 0, SumSquaresClass<int>() ); Copyright 2003, Kip R.Irvine 39 Optional Information Copyright 2003, Kip R.Irvine 40 deque sequence container pronounced "deck" provides benefits of vector and list in the same container • • • • • rapid indexed access (like vector) efficient insertion & deletion at its ends (like list) supports random-access iterators often used for FIFO queue noncontiguous memory layout Copyright 2003, Kip R.Irvine 41 Common deque operations push_back( ) push_front( ) pop_back( ) pop_front( ) size( ) operator [ ] at( ) Copyright 2003, Kip R.Irvine 42 deque Example #1 Create a deque containing pointers to strings: deque<Message *> mque; mque.push_back( mque.push_back( mque.push_back( mque.push_back( new new new new Message( Message( Message( Message( "John", "How are you?" )); "Sam", "What's happening?" )); "Anne", "What's for dinner?" )); "Bill", "Let's go surfing!" )); Copyright 2003, Kip R.Irvine 43 deque Example #1 Serve all messages from the front of the queue until the queue is empty: while( mque.size( ) > 0 ) { cout << **(mque.begin( )) << endl; mque.pop_front( ); } see dequeDemo.cpp Copyright 2003, Kip R.Irvine 44 The End Copyright 2003, Kip R.Irvine 45