Next: Explicit template instantiation, Previous: Using C++ standard library templates, Up: Templates
In addition to the template classes provided by the C++ standard library
you can define your own templates. The recommended way to use templates
with g++
is to follow the inclusion compilation model,
where template definitions are placed in header files. This is the
method used by the C++ standard library supplied with GCC itself. The
header files can then be included with ‘#include’ in each source
file where they are needed.
For example, the following template file creates a simple
Buffer<T>
class which represents a circular buffer holding
objects of type T
.
#ifndef BUFFER_H #define BUFFER_H template <class T> class Buffer { public: Buffer (unsigned int n); void insert (const T & x); T get (unsigned int k) const; private: unsigned int i; unsigned int size; T *pT; }; template <class T> Buffer<T>::Buffer (unsigned int n) { i = 0; size = n; pT = new T[n]; }; template <class T> void Buffer<T>::insert (const T & x) { i = (i + 1) % size; pT[i] = x; }; template <class T> T Buffer<T>::get (unsigned int k) const { return pT[(i + (size - k)) % size]; }; #endif /* BUFFER_H */
The file contains both the declaration of the class and the definitions
of the member functions. This class is only given for demonstration
purposes and should not be considered an example of good programming.
Note the use of include guards, which test for the presence of the
macro BUFFER_H
, ensuring that the definitions in the header
file are only parsed once if the file is included multiple times in the
same context.
The program below uses the templated Buffer
class to create a
buffer of size 10, storing the floating point values 0.25 and
1.0 in the buffer:
#include <iostream> #include "buffer.h" using namespace std; int main () { Buffer<float> f(10); f.insert (0.25); f.insert (1.0 + f.get(0)); cout << "stored value = " << f.get(0) << '\n'; return 0; }
The definitions for the template class and its functions are included in the source file for the program with ‘#include "buffer.h"’ before they are used. The program can then be compiled using the following command line:
$ g++ -Wall tprog.cc $ ./a.out stored value = 1.25
At the points where the template functions are used in the source file,
g++
compiles the appropriate definition from the header file and
places the compiled function in the corresponding object file.
If a template function is used several times in a program it will be stored in more than one object file. The GNU Linker ensures that only one copy is placed in the final executable. Other linkers may report “multiply defined symbol” errors when they encounter more than one copy of a template function—a method of working with these linkers is described below.