C++ Templates: Characteristics of Generic Libraries
C++ Templates: Characteristics of Generic Libraries
C++ Templates
09/03/2011
Templates
Function templates
Specify entire range of related (overloaded) functions Function-template specializations
Class templates
Specify entire range of related classes
Class-template specializations
Function Templates
Overloaded functions
Similar operations
Different types of data
Function templates
Identical operations
Different types of data
09/03/2011
Function Templates
Function-template definitions
Keyword template List formal type parameters in angle brackets (< and >)
Each parameter preceded by keyword class or typename
class and typename interchangeable template< class T > template< typename ElementType > template< class BorderType, class FillType >
Specify types of
Arguments to function Return type of function Variables within function
5
Function Templates
Current scenario
We rewrite functions Min(), Max(), and InsertionSort() for many different types There has to be a better way
Function template
Describes a function format that when instantiated with particulars generates a function definition
Write once, use multiple times
6
09/03/2011
PrintFloat(angle);
7
Function Overloading
The use of the same name for different C++ functions, distinguished from each other by their parameter lists
Eliminates need to come up with many different names for identical tasks. Reduces the chance of unexpected results caused by using the wrong function name.
8
09/03/2011
Function Overloading
void Print( { cout << cout << } void Print( { cout << cout << } void Print( { } int n ) "***Debug" << endl; "Value is " << n << endl; char ch ) "***Debug" << endl; "Value is " << ch << endl; float x )
To output the traced values, we insert:
Function Template
A C++ language construct that allows the compiler to generate multiple versions of a function by allowing parameterized data types.
TemplateParamDeclaration: placeholder
09/03/2011
Template argument
11
12
09/03/2011
13
Instantiated functions require two actual parameters of the same type. Their type will be the actual value for T
14
09/03/2011
15
Generic Sorting
template <class T> void InsertionSort(T A[], int n) { for (int i = 1; i < n; ++i) { if (A[i] < A[i-1]) { T val = A[i]; int j = i; do { A[j] = A[j-1]; --j; } while ((j > 0) && (val < A[j-1])); A[j] = val; } } }
16
09/03/2011
Template Functions One Function Definition (a function template) Compiler Generates Individual Functions
17
Class Template
Rules
Type template parameters Value template parameters
Place holder for a value Described using a known type and an identifier name
Template parameters must be used in class definition described by template Implementation of member functions in header file
Compilers require it for now
18
09/03/2011
Class Template
A C++ language construct that allows the compiler to generate multiple versions of a class by allowing parameterized data types.
TemplateParamDeclaration: placeholder
10
09/03/2011
22
11
09/03/2011
Substitution Example
class GList_int { public:
int int
void Insert( /* in */ ItemType item ); void Delete( /* in */ ItemType item ); bool IsPresent( /* in */ ItemType item ) const; private: int length; ItemType data[MAX_LENGTH]; }; int int
23
12
09/03/2011
25
Generic Arrays
template <class T> class Array { public: Array(int n = 10, const T &val = T()); Array(const T A[], int n); Array(const Array<T> &A); ~Array(); int size() const { return NumberValues; } Array<T> & operator=(const Array<T> &A); const T& operator[](int i) const; T& operator[](int i); private: int NumberValues; T *Values; };
26
13
09/03/2011
Default Constructor
template <class T> Array<T>::Array(int n, const T &val) { assert(n > 0); NumberValues = n; Values = new T [n]; assert(Values); for (int i = 0; i < n ++ i) { Values[i] = A[i]; } }
27
Copy Constructor
template <class T> Array<T>::Array(const Array<T> &A) { NumberValues = A.size(); Values = new T [A.size()]; assert(Values); for (int i = 0; i < A.size(); ++i) { Values[i] = A[i]; } }
28
14
09/03/2011
Destructor
template <class T> Array<T>::~Array() { delete [] Values; }
29
Example:
a swap function
15
09/03/2011
Template Syntax:
The template<> line states that everything in the following declaration or definition is under the subject of the template. (In this case, the definition is the function swap)
swap dissected
In here goes a list of placeholders variables. In almost all cases, they will be specified with either the typename or class keywords. These two keywords are equivalent.
Template behavior: Like most things in C++, templates attempt to behave as if it were a natural part of the language. It fails. There are two ways to use templates, implicit and explicit specialization. Explicit specialization always works. Implicit sometimes works. Why ever use implicit specialization? Its much cleaner. What are they? That is explained on the next slide.
31
Placeholder variables have one value within each template declaration. Think of them as being replaced by whatever type you specify the template to be.
Template Syntax:
Using a template
Using it
template <typename T> void swap(T &a, T &b) { T c = a; a = b; b = c; }
To use a template, one has to specialize it. This is why it isnt quite a generic function. It does static polymorphism. It morphs itself to the right type during preprocess time.
Syntax
To explicitly specialize a template, write its name with the arguments for the placeholder variables in angle brackets. This method always works. Example:
double d1 = 4.5, d2 = 6.7; swap<double>(d1, d2);
Templates however can auto-sense its placeholder values if all information about what the placeholders represent can be inferred from its context (arguments, and for member functions, the associated class instance). This is called implicit specialization. In the previous case, the compiler is smart enough to figure out that T is a double even without the explicit <double> since the arguments are doubles. Thus this shorthand works: Example:
swap(d1, d2);
32
16
09/03/2011
Class Templates:
Syntax:
Class Definition
Templated classes basically follow same syntax as templated functions. However, the rules for which templated classes can infer their specialization (see Template Syntax) are a bit more convoluted.
Answer:
Yes, they are equivalent. This may be relevant when writing class templates as it is possible that a situation may arise where two definitions are written for the same thing. If this happens, the program will not build since there are two equivalent function definitions. The name of the placeholder doesnt matter, and typename and class can be used interchangeably. Just something to remember.
33
Class Templates:
Notice the only addition to the class definition is the line:
template <typename T>
Example
Within the the definition block, the placeholder has can be used as a data type. When the template is specialized, it takes on the value of the specialization.
The header is pretty pedestrian. Lets have some fun. On to the fiery pits of class implementation.
File: Matrix.h
17
09/03/2011
Class Templates:
#include "Matrix.h" template <typename T> Matrix<T>::Matrix() {}
Example contd
template <typename T> T* Matrix<T>::operator[](int i) { return m_linArray + (i*m_cols); } template <typename T> void Matrix<T>::copy(const Matrix &other) { m_rows = other.m_rows; m_cols = other.m_cols; int size = m_rows * m_cols; m_linArray = new T[size]; for( int i=0; i < size; i++ ) { m_linArray[i] = other.m_linArray[i]; } } template <typename T> int Matrix<T>::getRows() const { return m_rows; } template <typename T> int Matrix<T>::getCols() const { return m_cols; }
template <typename T> Matrix<T>::Matrix(int rows, int cols) { m_rows = rows; m_cols = cols; m_linArray = new T[m_rows * m_cols]; } template <typename T> Matrix<T>::Matrix(const Matrix &other) { copy(other); } template <typename T> Matrix<T>::~Matrix() { delete[] m_linArray; } template <typename T> Matrix<T>& Matrix<T>::operator=(const Matrix &other) { if( this != &other ) { delete[] m_linArray; copy(other); } return *this; }
File: Matrix.cc
35
Shotgun Safety:
/* main.cc */ #include <iostream> using namespace std; #include <Matrix.h>
An example
The proper procedure Write the template, separated into a header and an implementation file Create an instantiation file for the template which include the implementation file. Compile the instantiation file and not the template implementation file. The instantiation file generates the object code for the template.
/* MatrixInst.cc */ #include Matrix.cc template Matrix<int>;
Example:
To make the previously unlinking piece of code link properly, it is necessary to instantiate an integer version of the Matrix template. The file would simply look like this
This line forces the instantiation of the Matrix class template, as well as all its member functions, for specialization int. Other specializations require their 36 own lines.
18