CIS Logo SVC Logo

   Computing & Information Systems
   Department

 

Schoology Facebook        Search CIS Site      Tutorials

Software Design Using C++



Introduction to the STL



What is the STL?


The Standard Template Library provides container classes for many data structures. Here is a partial list: vector, list, map, deque (double-ended queue), stack, queue, set, etc. Each such class provides typical functions for inserting a data item, removing an item, etc. The STL also provides algorithms, which are usually more involved than the container class functions. These algorithms can typically be used on any of the container classes. Examples of often-used algorithms are sort routines and search routines. Also, the STL uses iterators, which are sort of generalized pointers, that allow you to move through the items in a container.

Some practical matters need to be mentioned here. To use the STL, you need to include the appropriate header and use the std namespace. If you wish to use some of the algorithms, then you must also include the algorithm header. The various function and class names of the STL are located in the std namespace so as to avoid conflicts with names that the programmer might create. Since it is a nuisance to have to write something like std::vector, one typically puts a using namespace std; line at the top of one's code file. This allows you to just refer to vector instead of std::vector, and so on. However, the disadvantage of this approach is that you may run into name conflicts.

Templates


Since the STL uses templates heavily, let's begin by looking at the topic of templates themselves. Too often in the past programmers have had to write nearly identical code, say to sort an array, simply because in one case they needed to sort an array of floats, in another case an array of ints, and in another case an array of objects. This is ridiculous! A template function (or generic function) allows one to write the code once and then use that function with various data types.

The first two examples below use such template functions. In the first one, an array of integers is sorted and printed, whereas in the second one, an array of objects is sorted and printed. The template functions for sorting, swapping, and printing are exactly the same in these two programs. Based on how each of these functions is called, the compiler creates the appropriate specialization, or instance of the function. Even in the same program, one could call the BubbleSort template function twice, once to sort an array of ints and once to sort an array of floats. The compiler would include the two needed specializations of the generic BubbleSort routine. The important thing is that the programmer only has to write the code for sorting once.

Template Examples

In the first example above, note how the PrintArray function is set up to use a generic data type T as the component type for the array:


template <class T> void PrintArray(T DataArray[], int Count)

In the code for the Swap function, you see that the parameters are reference parameters of type T. Also, there is a local variable of type T.


template <class T> void Swap(T & First, T & Second)
   {
   T Temp;

The template <class T> in front of the function name indicates that this function uses a generic type named T. (You can, of course, name it something other than T.) Note that the PrintArray function uses the << operator to write data of type T to an output stream. Therefore, this operator must be available for whatever data type we use in our program. Similarly, the Swap function assumes that assignment works for data of type T, while the BubbleSort function assumes that the > operator works.

In the first example program, these assumptions are not a problem since the program uses an array of ints, and these operators all work for ints. In the second program, which uses an array of objects, the class has to be set up to provide overloaded operators that work with objects of the class. That is a bit of a nuisance, but once this is done, the exact same BubbleSort and PrintArray functions work. Having generic array-sorting and array-printing functions is very helpful. They make code reuse so much more practical!

The third example above shows how to set up a template class (also called a generic class). This program has a template-based class called ArrStackClass that provides an array implementation of stacks. The nice feature about the generic class is that it can be used to provide a stack of integers and a stack of characters, with no change to the class or its functions. This particular example creates one stack of each, both in the same program.

The template <class T> in front of the class declaration indicates that this class uses a generic type named T. Note that an object of this class contains a private data field, Info, which is an array of items of type T. Note the way that the prototypes for the class functions are written. For example, here is the one for Pop:


template <class T> void ArrStackClass<T>::Pop(T & Item)

Then, when you go to create an object belonging to this class, you need to specify what type gets used for T. For example, to create a stack S of integers you would use something like this:


ArrStackClass<int> S;

Optional Template Examples


The purpose of this section is to show you a few more advanced things that can be done with templates. However, this section is marked as optional since these features of templates are not used as often as the ones above.
Example templat4.cpp shows that a template function can use two (or more) generic types, not just one. The particular template function used in this example simply prints a pair of items. The interesting feature is that the two items do not have to be of the same type. Here is the code for this function:


template <class TypeA, class TypeB> void Output2(TypeA First, TypeB Second)
   {
   cout << First << "  " << Second << endl;
   }

In templat5.cpp a template class is set up that is parameterized by two types. This template class is named OrderedPair since objects of this class are ordered pairs of values, where the two values in a given pair do not have to be of the same type. The test program sets up and prints various ordered pairs. The class declaration itself is shown below. Follow the link to the example for the function definitions.


template <class TypeA, class TypeB> class OrderedPair
   {
   private:
      TypeA First;
      TypeB Second;
   public:
      OrderedPair(TypeA InitFirst, TypeB InitSecond);
      void SetFirst(TypeA NewFirst);
      void SetSecond(TypeB NewSecond);
      void GetFirst(TypeA & FirstValue) const;
      void GetSecond(TypeB & SecondValue) const;
      void Print(void) const;
   };

Finally, the optional example templat6.cpp contains a template function that displays the maximum of a pair of values. Both items in the pair must be of the same generic type T. The function returns the maximum in the function name, just to show that this can be done. An alternate way, of course, would be to return the maximum in a reference parameter. Here is the function definition:


template <class T> T Maximum(T First, T Second)
   {
   if (First > Second)
      return First;
   else
      return Second;
   }

Back to the main page for Software Design Using C++

Author: Br. David Carlson with contributions by Br. Isidore Minerd
Last updated: August 27, 2009
Disclaimer