Top Banner
Templates
32

. Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Dec 19, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Templates

Page 2: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Example…

A useful routine to have is

void Swap( int& a, int &b )

{

int tmp = a;

a = b;

b = tmp;

}

Page 3: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Example…

What happens if we want to swap a double ? or a string?

For each one, we need different function:void Swap( double& a, double &b )

{

double tmp = a; a = b; b = tmp;

}

void Swap( string& a, string &b )

{

string tmp = a; a = b; b = tmp;

}

Page 4: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Generic Programming

All these versions of Swap are “isomorphic”

// template code for Swap for arbitrary type T

void Swap( T& a, T &b )

{

T tmp = a;

a = b;

b = tmp;

}

Can we somehow tell the compiler to use Swap with any type T?

Page 5: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Templates

The template keyword defines “templates” Piece of code that will be regenerated with

different arguments each time

template<class T> // T is a “type argument”void Swap( T& a, T &b ) {T tmp = a; a = b; b = tmp;

}

Page 6: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Template Instantiation

int main()

{

int a = 2;

int b = 3;

Swap( a, b ); // requires Swap( int&, int& )

}

The compiler encounters Swap( int&, int& )

It instantiates the template Swap with T = int

and compiles the code defined by it

Page 7: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Template Instantiation

Different instantiations of a template can be generated by the same program

See Swap.cpp

Page 8: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Templates & Compilation A template is a declaration The compiler performs syntax checks only When a template is instantiated with specific

arguments, then the generated code is compiled

Implications: Template code has to be visible by the code

that uses it (i.e., appear in .h file) Compilation errors can occur only in a

specific instance (see Swap.cpp)

Page 9: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Another Example…

// Inefficient generic sort…

template< class T >

void

Sort( T* begin, T* end )

{

for( ; begin != end; begin++ )

for( T* q = begin+1; q != end; q++ )

if( *q < *begin )

Swap( *q, *begin );

}

See [Sort.h, TestSort.cpp]

Page 10: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

More Complex Case…

Suppose we want to avoid writing operator != for new classes

template <class T>

bool

operator!= (T const& lhs, T const& rhs)

{

return !(lhs == rhs);

}

When is this template used?

Page 11: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

More Complex Case…class MyClass {

public:

bool operator==(MyClass const & rhs) const;

};

int a, b;

if( a != b ) // uses built in operator!=(int,int)

MyClass x,y;

if( x != y ) // uses template with T = MyClass

Page 12: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

When Templates are Used?

When the compiler encounters…

f( a, b )

Search for a function f() with matching type signature

If not found, search for a template function that can be instantiated with matching types

Page 13: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Generic Classes?

Suppose we implement a class StrList that maintains a list of strings See StrList.h and StrList.cpp

The actual code for maintaining the list has nothing to do with the particulars of the string type

Can we have a generic implementation of lists?

Page 14: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Class Templates

template<class T>

class MyList {

};

MyList<int> intList; // T = int

MyList<string> stringList; // T = string

Page 15: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Class Templates

Code similar to usual code: Add template<…> statement before each

top-level construct Use template argument as type in class

definition

Implementation of methods, somewhat more complex syntax See MyList.h TestMyList.h

Page 16: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Constructing a List

We want to initialize a list from an array We can write a method that receives a

pointer to the array, and a size argumentint array[] = { 1, 2, 3, 4, 5, 6 };

MyList<int> list;

list.copy( array, 6 );

Alternative: use a pointer to initial position and one to the position after the lastlist.copy( array, array+6 );

This form is more flexible (as we shall see)

Page 17: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Constructing a List

// Fancy copy from array

template< class T >

MyList<T>::copy( T const* begin,

T const* end )

{

T const* p;

for( p = begin; p != end; p++ )

pushBack(*p);

}

Page 18: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Pointer Paradigm

Code like:T * p;

for( p = begin; p != end; p++ )

{

// Do something with *p

}

Applies to all elements in [begin,end-1] Common in C/C++ programs Can we extend it to other containers?

Page 19: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Iterator

Object that behaves just like a pointer Allows to iterate over elements of a container

Example:MyList<int> L;

MyList<int>::iterator i;

for( i = L.begin(); i != L.end(); i++ )

cout << " " << *i << "\n";

Page 20: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Iterators

To emulate pointers, we need: copy constructor operator = (copy) operator == (compare) operator * (access value) operator++ (increment)

Page 21: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

MyList<T> iterator

Keep a pointer to a nodeclass iterator {

private:

Node m_pointer;

};

Provide encapsulation, since through such an iterator we cannot change the structure of the list

See MyListWithIterators.h

Page 22: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Side Note operator++

In C we can use ++ in two forms: prefix notation ++x

increment x fetch x’s value

postfix notation x++ fetch x’s value increment x

How can we implement both variants?

Page 23: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Operator++

Prefix form:T& T::operator++();

Postfix formT T::operator++(int); // dummy argument!

Note different return types

See MyListWithIterators.h

Page 24: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Initializing a List

We now want to initialize a list from using parts of another list

Something liketemplate< class T >

MyList<T>::copy( iterator begin,

iterator end )

{

iterator p;

for( p = begin; p != end; p++ )

pushBack(*p);

}

Page 25: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Generic Constructor

The code for copying using T* MyList<T>::iterator

are essentially identical on purpose --- iterators mimic pointers

Can we write the code once?

Page 26: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Template within a templatetemplate < class T > class MyList {

template< class Iterator >

copy( Iterator begin, Iterator end )

{

for( Iterator p = begin; p != end; p++ )

pushBack(*p);

}

};

Page 27: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Copy Method

MyList<T>::copy() can be instantiated with different types pointer to T MyList<T>::iterator Iterators of other data structures that

contain objects of type T

Page 28: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Template Variations

Can receive constant argumentstemplate< class T, int Size = 1024>

class Buffer {

private:

T m_values[Size];

};

Buffer<char> Buff1;

Buffer<char,1024> Buff2; // same as Buff1

Buffer<int, 256> Buff3;

Page 29: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Template and Types

Buffer is not a type Buffer<char,1024> is a type Buffer<char>, buffer<char,1024> are two

names for the same type Buffer<char,256> is a different type

Page 30: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Class Templates - Recap

Provides support for generic programming Parameters are either types or constants.

Default values can be specified Depends only on the properties it uses from

its parameter types Resulting classes may be very efficient, but

code size may be larger Difficult to write, maintain and debug Class template overloading is impossible

Page 31: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Summary

Alternative mechanism to polymorphism

Write & Debug concrete example (e.g., StringList) before generalizing to a template

Understand iterators and other “helper” classes

Foundation for C++ standard library (STL)

Page 32: . Templates. Example… A useful routine to have is void Swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }

Things to read about

Standard Library <string> – implementation of string <algorithm> - algorithms (sort, swap, etc.) <utility> - relational operators