Template - University of Wisconsin

advertisement

Computer Science and Software Engineering

University of Wisconsin - Platteville

5. Template

Yan Shi

CS/SE 2630 Lecture Notes

Void Pointer

void * p;

// Declare like a normal pointer, use the // void keyword as the pointer type.

 AKA generic pointer : can be pointed at objects of any data type!

int num; float value = 1.2; p = # p = &value;

— One of its possible uses may be to pass generic parameters to a function.

 cannot be dereferenced ! We don’t know the type..

— cast the void pointer before dereference it

— cout << *static_cast<float*>( p );

 also cannot do pointer arithmetic ! same reason.

 Avoid using void pointers if possible. There are other ways to achieve genetic functions!

Generic

 What is the purpose of typedef Fruit InfoType;

 To make your operation/data structure more generic, we can use a template function/class.

Template: a C++ language construct that allows the compiler to generate multiple versions of a class type or a function by allowing parameterized type.

Function Template

template<class Type>

Type max(const Type &a, const Type &b)

{ return a > b ? a : b;

}

… max <int> ( 5, 9 ); max <Student> ( mike, alex );

 To declare: template < class identifier> function_declaration; template < typename identifier> function_declaration;

 To use: function_name <type> (parameters);

 Make sure the operations defined in the function template are defined for the type of objects that are using the template.

Function Template

 In some cases the compiler can automatically find out the type.

int i,j; max(i,j);

 We can also define function templates that accept more than one type of parameter: template <class T, class U>

T GetMin (T a, U b)

{ return ( a < b ? a : b );

}

… int i,j; long l; i = GetMin<int,long> (j,l);

Class Template

template<class ItemType> class Stack

{ protected: int height;

ItemType items[50]; public:

Stack() : height(0) { } void push( ItemType x) { items[height] = x; ++height; }

ItemType pop() { height--; return items[height]; } bool isEmpty() const { return height <= 0; } bool isFull() const { return height >= 50; }

};

Stack <Student> stuStack;

Stack <int> nums; nums.push(10);

Template Class

 At compile time, the compiler generates distinct class types and gives its own internal name to each type.

— Stack _Student stuStack;

— Stack _int nums;

 The new class types are called template classes.

 Similar to template functions.

Implementing Class Template

 Two options:

— put all code for template in .h

file //preferred!

— in the implementation file, precede the member function definition with the template <…> prefix template <class ItemType> void Stack<ItemType>::push(ItemType x)

{ items[height] = x;

++height;

}

 An implementation trick:

— drive template class from non-template class, put most code in base class class ComplexContainer

{ ... }; template<class T> class Container : public ComplexContainer

{...};

Non-Type Parameters

 Can also have multiple type parameters: template<class ItemType, int size> class Stack

{ protected: int height;

ItemType items[size]; public:

Stack() : height(0) { } void push(ItemType x) { items[height] = x; ++height; }

ItemType pop() { height--; return items[height]; } bool isEmpty() const { return height <= 0; } bool isFull() const { return height >= size; }

}

Stack<int, 100> st;

Type Checking

 Type checking is guaranteed when using class templates void DoIt(Stack<char, 10> chs) {…}

Stack<char, 20> letters; letters.push(“something”); //illegal!

DoIt(letters); //illegal!

 Solution: make DoIt a function template!

template<class T, int size> void DoIt(Stack<T, size> stack) {…}

Stack<char, 20> letters;

DoIt(letters); //OK!

inline Function

 keyword inline : function is treated as a macro inline template<class T> T sqr(const T &x)

{ return x * x; } the preprocessor converts the code cout << sqr(5); into cout << 5 * 5;

 Pros:

— no function call overhead

— compiler optimization

 Cons:

— Expand code if inline function is long

— hard to debug: it looks like a function is being called, but it's not really

 inline functions should only be in header files!

— compiler must see body of inline function to do the job.

 class members defined within class definition are automatically inlined.

Download