Templates -

Decide which algorithms you want: parameterize them so that they work for OOD and C++ a wide-range of types & data structures

Section 5: Templates Templates in C++ support generic progarmming

Templates provide: •simple way to represent general concepts •simple way to combine concepts

Use ‘data-types’ as parameters at compilation

Advantage: • more general ‘generic code’ • reuse same code for different data types • less bugs - only implement/debug one piece of code • no overhead on run-time efficiency compared to data specific code Use of Templates Templates in C++

Make the definition of your class as broad as possible! template class declaration: mytemplate.hh template class mytemplate { public: Widely used for container classes: mytemplate(); • Storage independent of data type void function(); • C++ Standard Template Library (Arrays,Lists,…..) protected: int protected_function(); Encapsulation: private: Hide a sophisticated implementation behind a simple double private_data; interface };

template : • specifies a template is being declared • type parameter ‘DataC’ (generic class) will be used • DataC can be any type name: class, built in type, typedef • DataC must contain data/member functions which are used in template implementation. Example - Generic Array Example - Generic Array (cont’d) simple_array.hh template class simple_array { private: #include “simple_array.hh” int size; DataC *array; #include “string.hh”

public: void myprogram(){ simple_array(int s); simple_array intarray(100); ~simple_array(); simple_array doublearray(200); DataC& operator[](int i); simple_array stringarray(500); }; for (int i(0); i<100; i++) template intarray[i] = i*10; simple_array::simple_array(int s) : size(s) { array = new DataC[size]; } // & the rest….. template }; simple_array::~simple_array(){ delete [ ] array; } inline template DataC& simple_array::operator[](int i){ if (i<0 || i>=size) {cerr << “Error …..\n”; exit(0);} return array[i]; } Template Instantiation Template Instantiation

mytemplate.hh template class template class mytemplate { public: Instantiations private: class class class …. class< > }; // define my template member functions here

(1) Instantiate by declaring a variable myprogram.cc Object code does not exist until template is instantiated #include “mytemplate.hh” •template is included as a header file void myprogram(){ mytemplate it; // instantiate integer version mytemplate dt; // instantiate double version Template is instantiated at compile time }; • No run-time overhead • Instantiation generates code for constructor/destructor & member functions which are used (2) Instantiation via inheritance • ‘Specialisation’ ie define class of a specific type myderivedclass.hh #include “mytemplate.hh Errors in template not detected until instantiation class myderivedclass: public mytemplate { public: Warning: Do not generate different templates for objects with private: only minor differences }; Results in ‘code-bloat’ => big increase in executable size. Template is instantiated when class is compiled => object code

Inheritance works as before: derived class sees public/protected Template Constructors & Member Functions Using Templates

All constructors/destructors/member functions declared Constructors declare type parameter: class, typedef, struct as before for classes. Member functions are used as before Note: Definition is in the template header file after declaration or in a file .tcc included at end of header file myprogram.cc mytemplate.hh #include “mytemplate.hh” #include “String.hh” // template declaration void myprogram(){ // constructor mytemplate ts(100); // constructor template mytemplate::mytemplate(args) : // setup member data from args StringC as; { as = ts.function(); // member function // other initialisation } }

// function Program instantiates construction and function() template int mytemplate::function(){ // perform some operation Object code is only compiled for constructor and function() } Template code for otherfunction() is not compiled // inline function inline template int mytemplate::otherfunction(){ // perform operation - no overhead of function call } Only Constructors/Member Functions which are used are instantiated Templates & Inheritance Templates vs. Inheritance

Template parameterizes the definition of a class with another class Both mechanism for building • building new types out of existing ones •Code implementing the template is identical for all parameters classes • exploiting commonality

Combine templates and inheritance Abstract class (): defines an interface • template either as base or derived class •Code implementing the abstract class is shared in class hierarchies Examples class Declarations (1) Derive one template from another

template class derived: public base{ Two approaches are similar: ‘polymorphic’ }; Templates => compile time polymorphism (2) Derive a non-template class from a template Abstract classes => run-time polymorphism class derived: public basetemplate{ }; When to use template vs abstract class? (3) Template class from non-template •use template where no hierachical is required between objects template derivedtemplate: public base{ •if types of objects are not known at compile time use }; classes derived from an abstract base class •if run-time efficienty is a priority use template (no overhead)

All common uses of templates + inheritance to build class structures Function Templates More Templates...

Specify a generic function (1) Template with multiple parameters •works for a broad range of types •avoids run-time overheads of type checking or virtual function •example associative array

swap.hh // function declaration template class mytemplate { template void swap(DataC& a, DataC& b); };

// function definition template void swap(DataC& a, DataC& b){ DataC temp(a); (2) Templates of Templates a=b; b=temp; •example: array of arrays (2d array) }

myprogram.cc template > class mytemplate { #include “swap.hh” }; void myprogram(){ int i(5), j(10); double u(5.5), v(9.8);

swap(i,j); // j=5 i=10 swap(u,v); // u=9.8 v=5.5 swap(i,u); // invalid different types - implicit cast } Designing & Implementing Templates Using separate files .hh & .tcc

(1) Design your classes to be general ‘generic’ template declaration & implementation is a header file - template is included & compiled when instantiated (2) Use templates to define common code for different single header file mytemplate.hh data types ie container classes //declaration template class mytemplate{ (3) Use templates with inheritance to define specific classes }; with common representations // definition template mytemplate::mytemplate(){ (4) Develop template code as a specific type } => for debugging ….. OR (5) Remember: template code for a member function is only compiled when a template is header file for declaration mytemplate.hh instantiated as a specific type template class mytemplate{ }; (6) Use a separate header file template declaration and #include “mytemplate.tcc” // include file for definition implementation .hh & .tcc header file for definition mytemplate.tcc template mytemplate::mytemplate(){ }

• separates ‘user-interface’ from implementation • simplifies structure (similar to .hh +.cc) • used in examples Example: Lists

•List structure: • Node: Stores individual list element data - information we want to store in list next - pointer to next element in list prev - pointer to previous element in list • List: The list itself (constructor/destructor) first - pointer to first Node in list • Iterator: external reference to a node in the list used to move to next/previous node

List

Node Node Node Node

Iterator