16.2.10 Templates

back: runtime type identification (rtti)
forward: default template arguments
 
fastback: exceptions
up: changeable c++
fastforward: compiler quirks
top: autoconf, automake, and libtool
contents: table of contents
index: index
about: about this document

Templates--known in other languages as generic types ---permit you to write C++ classes which represent parameterized data types. A common application for class templates is container classes. That is, classes which implement data structures that can contain data of any type. For instance, a well-implemented binary tree is not interested in the type of data in its nodes. Templates have undergone a number of changes since their initial inclusion in the ARM. They are a particularly troublesome C++ language element in that it is difficult to implement templates well in a C++ compiler.

Here is a fictitious and overly simplistic C++ class template that implements a fixed- sized stack. It provides a pair of methods for setting (and getting) the element at the bottom of the stack. It uses the modern C++ template syntax, including the new typename keyword (see section 16.2.8 The typename Keyword).

 
 template <typename T> class Stack { public:   T first () { return stack[9]; }   void set_first (T t) { stack[9] = t; } private:   T stack[10]; }; 

C++ permits this class to be instantiated for any type you like, using calling code that looks something like this:

 
 int main () {   Stack<int> s;   s.set_first (7);   cout << s.first () << endl;   return 0; } 

An old trick for fashioning class templates is to use the C preprocessor. Here is our limited Stack class, rewritten to avoid C++ templates:

 
 #define Stack(T) \   class Stack__##T##__LINE__ \   { \   public: \     T first () { return stack[0]; } \     void set_first (T t) { stack[0] = t; } \   \   private: \     T stack[10]; \   } 

There is a couple of subtleties being used here that should be highlighted. This generic class declaration uses the C preprocessor operator `##' to generate a type name which is unique amongst stacks of any type. The __LINE__ macro is defined by the preprocessor and is used here to maintain unique names when the template is instantiated multiple times. The trailing semicolon that must follow a class declaration has been omitted from the macro.

 
 int main () {   Stack (int) s;   s.set_first (7);   cout << s.first () << endl;   return 0; } 

The syntax for instantiating a Stack is slightly different to modern C++, but it does work relatively well, since the C++ compiler still applies type checking after the preprocessor has expanded the macro. The main problem is that unless you go to great lengths, the generated type name (such as Stack__int ) could collide with other instances of the same type in the program.


This document was generated by Gary V. Vaughan on May, 24 2001 using texi2html


GNU Autoconf, Automake and Libtool
GNU Autoconf, Automake, and Libtool
ISBN: 1578701902
EAN: 2147483647
Year: 2002
Pages: 290

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net