.Open The C++ Standard Template Library This is a short primer on the $STL or "Standard Template Library" for the programming language C++ as defined in the 1997 standard. The $STL is a collection C++ libraries that allow you to use several well known kinds of data structures with out having to program them. They are designed so that the code runs efficiently. The compiler does most of the work of generating the efficient implementations. The libraries include a large number of possibilities. I describe some of things you can do with the STL versions of stacks, queues, vectors, and lists. I define some important and useful ideas in the $Glossary below. The is a table summarizing the methods used with stacks, queues, vectors and lists at $Summary below. For each kind of data structure I give working examples of how to declare, access and use objects of that type. .Open Standard Templates The international and American Standard for C++ requires there to be special libraries that implement the following generic data structures: .Table Library Description More Info .Row <$vector> A dynamic array .See $Vectors .Row <$list> A randomly changing sequence of items .Item $Lists .Row <$stack> A sequence of items with $pop and $push at one end only .Item $Stacks .Row <$queue> A Sequence of items with $pop and $push at opposite ends .Item $Queues .Row Double Ended Queue with pop and push at both ends .Item $More .Row A subset of of a fixed and small set of items .Item $More .Row An unordered collection of items .Item $More .Row An collection of pairs of items indexed by the first one .Item $More .Close.Table These are designed to be general, efficient, and powerful rather than easy to use. .Close Standard Templates .Open Stacks Stacks are only accessed at their top. To be able to use $STL stacks in a file of C++ source code or a header file add .As_is #include at the beginning of the file. Suppose that `T` is any type or class - say an int, a float, a struct, or a class, then .As_is stack s; declares a new and empty stack called `s`. Given `s` you can: .Set test to see if it is empty: .As_is s.empty() find how many items are in it: .As_is s.size() push a `t` of type `T` onto the top: .As_is s.push(t) pop the top off `s`: .As_is s.pop() get the top item of `s` .As_is s.top() change the top item: .As_is s.top() = expression. .Close.Set . Example of an STL Stack .As_is void reverse(string & x) .As_is //Afterwards x will have the same elements in the opposite order. .As_is { .As_is stack s; .As_is const int n = x.length(); .As_is //Put characters from x onto the stack .As_is for(int i=0; i > s; or .As_is stack< list > s; See $Errors below for some common mistakes and problems (like omitting a space in the wrong place above). .As_is void reverse(string & x) //INOUT: x is a string of characters .As_is //Afterwards x will have the same elements in the opposite order. .As_is { .As_is stack< vector > s; .As_is .As_is const int n = x.length(); .As_is for(int i=0; i Suppose that `T` is any type or class - say an int, a float, a struct, or a class, then .As_is queue q; declares a new and empty queue called `q`. Given an object `q`: .Set test to see if `q` is empty: .As_is q.empty() find how many items are in `q`: .As_is q.size() push a `t`:`T` onto the end of `q`: .As_is q.push(t) pop the front of `q` off `q`: .As_is q.pop() get the front item of `q`: .As_is q.front() change the front item: .As_is q.front() = expression. get the back item of `q`: .As_is q.back() change the back item: .As_is q.back() = expression. .Close.Set .See Errors below. .As_is // A simple example of putting three items into a queue and .As_is // then taking them off the queue. .As_is #include .As_is #include .As_is #include .As_is .As_is int main() .As_is { .As_is queue q; .As_is .As_is q.push('a'); .As_is q.push('b'); .As_is q.push('c'); .As_is .As_is cout << q.front(); .As_is q.pop(); .As_is .As_is cout << q.front(); .As_is q.pop(); .As_is .As_is cout << q.front(); .As_is q.pop(); .As_is } . Older Queues On some older C++ libraries you are forced to indicate how the queue is implemented whenever you declare one. You write .As_is queue< list > q; in place of .As_is queue< T > q; .See Errors below. .As_is // A simple example of putting three items into a queue and .As_is // then taking them off the queue. .As_is #include .As_is #include .As_is #include .As_is .As_is int main() .As_is { .As_is queue< list >q; .As_is .As_is q.push('a'); .As_is q.push('b'); .As_is q.push('c'); .As_is .As_is cout << q.front(); .As_is q.pop(); .As_is .As_is cout << q.front(); .As_is q.pop(); .As_is .As_is cout << q.front(); .As_is q.pop(); .As_is } .Close Queues .Open Lists Lists are good when data needs to be reorganized a lot. To be able to use $STL lists add this before you start using them in your source code: .As_is #include Suppose that `T` is any type or class - say an int, a float, a struct, or a class, then .As_is list l; declares a new and empty list called `l`. Given an object `l`: .Set test to see if `l` is empty: .As_is l.empty() find how many items are in `l`: .As_is l.size() push a `t`:`T` onto the end of `l`: .As_is l.push_back(t) pop the last off `l`: .As_is l.pop_back() push a `t`:`T` onto the start of `l`: .As_is l.push_front(t) pop the front of `l` off `l`: .As_is l.pop_front() get the front item of `l`: .As_is l.front() change the front item: .As_is l.front() = expression. get the back item of `l`: .As_is l.back() change the back item: .As_is l.back() = expression. Sort the list: .As_is l.sort() Clear the list: .As_is l.clear() Merge in a sorted list into a sorted list: .As_is l.merge(list_of_sorted_elements) Reverse the list: .As_is l.reverse() Assign a copy of `q1` to `q`: .As_is q = q1 Insert and delete items inside a List .See Lists and Iterators Efficiently visit each item in turn, see $Iterators below. .Close.Set . Example of List Processing This uses a utility function 'print' that is implemented below .See An Example of Iterating Through a List . Building and Sorting a List .As_is //Using a list to sort a sequence of 9 numbers. .As_is #include .As_is #include .As_is // #include .As_is .As_is void print(list a);//utility function print lists of ints .As_is .As_is int main() .As_is { .As_is list a; .As_is //Put 9,8,7,6,5,4,3,2,1 onto the list .As_is for(int i=0; i<9;++i) .As_is a.push_back(9-i);// put new element after all the others .As_is .As_is print(a); //here the list contains (9,8,7,6,5,4,3,2,1) .As_is a.sort();//in the library! .As_is print(a); //here the list contains (1,2,3,4,5,6,7,8,9) .As_is } .Close Lists .Open Vectors Vectors are good when we have an unknown sequence of items to store but we want to access the by their sequence numbers. To be able to use $STL vectors add this before you start using them in your source code: .As_is #include .See Errors Suppose that `T` is any type or class - say an int, a float, a struct, or a class, then .As_is vector v; declares a new and empty $vector called `v`. Given object `v` declare like the above: .Set test to see if `v` is empty: .As_is v.empty() find how many items are in `v`: .As_is v.size() push a `t`:`T` onto the end of `v`: .As_is v.push_back(t) pop the front of `v` off `v`: .As_is v.pop_back() get the front item of `v`: .As_is v.front() change the front item: .As_is v.front() = expression. get the back item of v: .As_is v.back() change the back item: .As_is v.back() = expression. Access the `i`'th item (0<=`i` and vector<`T`> are $Containers. So there are iterator classes called .As_is list::iterator and they are used like this: .As_is for( list::iterator p=c.begin(); p!=c.end(); ++p) .As_is process(*p); Vector iterators have type .As_is vector::iterator and used like this: .As_is for( vector::iterator p=c.begin(); p!=c.end(); ++p) .As_is process(*p); If you change your choice from a $vector to a $list then the code is almost identical. This makes your code easier to modify. For any $container class `C` of objects type `T` and any object `c` of type `C`: .Set Declare an iterator for $container of type C. .As_is C::iterator p Move iterator `p` onto the next object in `c`(if any!). .As_is ++p The value selected by `p`. .As_is *p The iterator that refers to the first item in `c` .As_is c.begin() The iterator that refers to one beyond `c`. .As_is c.end() Declare an iterator for $container of type `C` and set to the start of `c`. .As_is C::iterator p = c.begin(); Test to see if iterator p has come to the end of object `c`: .As_is p != c.end(); assign `p1` to `p` -- afterwards both refer to same item .As_is p = p1; .Close.Set . Lists and Iterators Insertion and deletion of items at the start or inside a List of elements is controlled by an iterator: .Set Insert item `x` into List `l` before iterator `p` .As_is l.insert(p, x); Erase the element pointed at by iterator `q` in List `l` .As_is l.erase(q); .Close.Set .As_is #include .As_is #include .As_is void print(list );// elsewhere .As_is main() .As_is { list l; .As_is list ::iterator p; .As_is l.push_back('o'); l.push_back('a'); l.push_back('t'); .As_is .As_is p=l.begin(); .As_is cout <<" "<< *p< a) .As_is { .As_is for(list::iterator ai=a.begin(); ai!=a.end(); ++ai) .As_is cout << *ai << " "; .As_is .As_is cout << endl; .As_is cout << "----------------"<` then .As_is vector::iterator is the class of suitable iterators. Here are two useful values: .As_is v.begin() .As_is v.end() These always form a $range of all the items in `v` from the $front up to and including the $back. You can sort a $vector v simply by writing: .As_is sort(c.begin(), c.end()); .As_is //Sorting a vector with 9 integers .As_is #include .As_is #include .As_is #include .As_is .As_is void print( vector ) ;//utility function outputs a $container .As_is .As_is int main() .As_is { .As_is vector a; .As_is // Place 9,8,7,6,5,4,3,2,1 into the vector .As_is for(int i=0; i<9;++i) .As_is a.push_back(9-i);// put new element after all the others .As_is .As_is print(a); // elements of a are (9,8,7,6,5,4,3,2,1) .As_is .As_is sort( a.begin(), a.end() ); //in the STL library .As_is .As_is print(a); // elements are nor in order. .As_is } .As_is .As_is .As_is void print( vector a) .As_is { .As_is for(vector::iterator ai=a.begin(); ai!=a.end(); ++ai) .As_is cout << *ai << " "; .As_is .As_is cout << endl; .As_is cout << "----------------"<" signs below: .As_is stack< vector< T > > s; If the standard and is not found then you are using an older C++ compiler. You may still be able to a slightly different form of stack and queue however: .See Older Stacks .See Older Queues On some older compilers and currant libraries when you need a as well as either or you need to .As_is #include before including the list or vector rather in the reverse order! Older string library appear to define some special versions of vector and list operators and the older compilers can not make up its mind which to use. . Acknowledgements Dr. Botting wants to acknowledge the help and advice given by Dr. Zemoudeh about this document. Whatever errors remain are Dr. Botting's mistakes. .Close The C++ Standard Template Library