Вы находитесь на странице: 1из 36

Templates

Objectives

To know the motivation and benefits of templates To declare template function with type parameters

To develop generic classes using class templates

Template Basics

Templates make it possible to use one function or class to handle many different data types In other words, templates provide the capability to parameterized types in function and classes. With this capability, you can define one function or one class with a generic type that can be substituted for a concrete type by a compiler So, template concept can be used in two different ways:

with functions and with classes

Template Basics (A Function Template)

Template Basics
int maxValue(int value1, int value2) { if (value1 > value2) return value1; else return value2; }
int maxValue(double value1, double { if (value1 > value2) return value1; else return value2; } value2)

int maxValue(char value1, char value2) { if (value1 > value2) return value1; else return value2; }

Generic Function

GenericType maxValue(GenericType value1, GenericType value2) { if (value1 > value2) return value1; else return value2; }

Generic Function

C++ enables you to define a function template with generic types. Match Parameter:

The generic maxValue function can be used to return a maximum of two values of any type, provided that
The two values have the same type The two values can be compared using the > operator

Template Basics
template<class T> T maxValue(T value1, T value2) { if (value1 > value2) return value1; else return value2; } void main() { cout << "Maximum between 1 and 3 is " << maxValue(1, 3) << endl; cout << "Maximum between 1.5 and 0.3 is "<< maxValue(1.5, 0.3) << endl; cout << "Maximum between 'A' and 'N' is " << maxValue('A', 'N') << endl; cout << "Maximum between \"ABC\" and \"ABD\" is "<< maxValue("ABC", "ABD") << endl; }

Generic Function

The template keyword signals the compiler that were about to define a function template.

The keyword class, within the angle brackets, might just as well be called type. The variable following the keyword class (T in this example) is called the template argument.
The function template itself doesnt cause the compiler to generate any code. It cant generate code because it doesnt know yet what data type the function will be working with. It simply remembers the template for possible future use.

Function Template Instantiation

Code generation doesnt take place until the function is actually called (invoked) by a statement within the program.

When the compiler sees such a function call, it knows that the type to use, say it is int. So, it generates a specific version of the function for type int, substituting int wherever it sees the name T in the function template. This is called instantiating the function template.
Each instantiated version of the function is called a template function. (That is, a template function is a specific instance of a function template).

Advantages of using Templates

The amount of RAM used by the program is the same whether we use the template approach or actually write three separate functions. The template approaches simply saves us from having to type three separate functions into the source file. This makes the listing shorter and easier to understand. If change is required the way the function works, make the change in only one place in the listing instead of three places.

The Deciding Parameter/Argument


The compiler decides how to compile the function based entirely on the data type used in the function calls argument (or arguments). The functions return type doesnt enter into this decision.
This is similar to the way the compiler decides which of several overloaded functions to call.

<typename T> Preferred

You can use either <typename T> or <class T> to specify a type parameter. Using <typename T> is better because <typename T> is descriptive. <class T> could be confused with class declaration.

Multiple Type Parameters

Occasionally, a template function may have more than one parameter. In this case, place the parameters together inside the brackets, separated by commas, such as <typename T1, typename T2, typename T3>

Multiple Type Parameters


template <class atype> int find(atype* array, atype value, int size) { for(int j=0; j<size; j++) if(array[j] == value) return j; return -1; } char chrArr[] = {1, 3, 5, 9, 11, 13}; char ch = 5; int intArr[] = {1, 3, 5, 9, 11, 13}; int in = 6; long lonArr[] = {1L, 3L, 5L, 9L, 11L, 13L}; long lo = 11L; double dubArr[] = {1.0, 3.0, 5.0, 1.0, 9.0}; double db = 4.0; void main() { cout << \n 5 in chrArray: index=; cout<<find(chrArr, ch, 6); cout << \n 6 in intArray: index=; cout<<find(intArr, in, 6); cout << \n11 in lonArray: index=; cout<<find(lonArr, lo, 6); cout << \n 4 in dubArray: index=; cout<<find(dubArr, db, 6); cout << endl; }

Template Issues

Template Arguments must match

When a template function is invoked, all instances of the same template argument must be of the same type. For example, in find(), if the array name is of type int, the value to search for must also be of type int.

int intarray[] = {1, 3, 5, 7}; float f1 = 5.0; int value = find(intarray, f1, 4); //

The compiler expects all instances of atype to be the same type. It can generate a function find(int*, int, int); but it cant generate find(int*, float, int); because the first and second arguments must be the same type.

template<class atype> int find(atype* array, atype value, int size) { // another way of declaration in one line }

More than One Template Arguments


template <class atype, class btype> btype find(atype* array, atype value, btype size) { for(btype j=0; j<size; j++) if(array[j]==value) return j; return static_cast<btype>(-1); }

Template Basics (A Class Template)

Specific Type Array Classes


#define MAX 5 #define MAX 5 class IntArr class Double { { private: private: int ara[MAX]; double ara[MAX]; public: public: void input() void input() { { for(int i=0; i<MAX; i++) for(int i=0; i<MAX; i++) cin<<arr[i]; cin<<arr[i]; } } void output() void output() { { cout<<Values in Array\n; cout<<Values in Array\n; for(int i=0; i<MAX; i++) for(int i=0; i<MAX; i++) cout<<arr*i+<< \t; cout<<arr*i+<< \t; } } }; };

Class Templates (Generic Array)


#define MAX 5 template <class T> class ArrTemp { private: T ara[MAX]; public: void input() { for(int i=0; i<MAX; i++) cin<<arr[i]; } void output() { cout<<Values in Array\n; for(int i=0; i<MAX; i++) cout<<arr*i+<< \t; }
};

void main() { ArrTemp<int> arr1; ArrTemp<double> arr2; ArrTemp<char> arr3;


cout<<Input integer values\n; arr1.input(); cout<<Input double values\n; arr2.input(); cout<<Input char values\n; arr3.input(); arr1.output(); arr2.output(); arr3.output(); }

Specific Type Stack Classes


#define MAX 5 class LongStack { private: long st[MAX]; int top; public: LongStack(); void push(long var); long pop(); }; #define MAX 5 class FloatStack { private: float st[MAX]; int top; public: FloatStack(); void push(float var); float pop(); };

Class Templates (Generic Stack)


const int MAX = 100; template <class Type> class Stack { private: Type st[MAX]; int top; public: Stack() { top = -1; } void push(Type var) { st[++top] = var; } Type pop() { return st[top--]; }
void main() { Stack<float> s1; s1.push(1111.1F); s1.push(2222.2F); s1.push(3333.3F); cout << 1: << s1.pop() << endl; cout << 2: << s1.pop() << endl; cout << 3: << s1.pop() << endl; Stack<long> s2; s2.push(123123123L); s2.push(234234234L); s2.push(345345345L); cout << 1: << s2.pop() << endl; cout << 2: << s2.pop() << endl; cout << 3: << s2.pop() << endl; }

};

Standard Template Library (STL)

Slides Modified From Students Presentation


Hajra Qayyum

Shawana Khan
Laila Farrukh

STL Introduction

The STL is a C++ software library


Collections of useful classes for common data structures Ability to store objects of any type (template)

The STL contains several kinds of entities. The three most important are
Containers Algorithms Iterators

STL Introduction

Relationship between Containers, Algorithms, and Iterators

STL Container

A Container is a way that stored data is organized in memory


Data may consists of built-in types such as int, and float, or of class objects Containers in the STL can be categorized into: Sequence containers Adapter containers Associative containers

STL Container

Sequence Container
Stores data by position in linear order First element, second element , etc Examples: Array, vector, list, deque

Associate Container Not sequential, instead it uses key to access data Stores elements by key, such as name, social security number or part number Access an element by its key which may bear no relationship to the location of the element in the container Examples: set, multiset, map, multimap Adapter Container Contains another container as its underlying storage structure Examples: stack, queue, priority queue

STL Member Functions

STL Algorithms

An algorithm is a function that does something to the items in a container (or containers)
Algorithms in STL are standalone template functions The header <algorithm> defines a collection of functions especially designed to be used on ranges of elements A range is any sequence of objects that can be accessed through iterators or pointers, such as an array or an instance of some of the STL containers.

STL Iterator

Iterators are pointer-like entities that are used to access individual data items (which are usually called elements), in a container Often they are used to move sequentially from elements to elements, a process, called iterating through the container

Three major classes of Iterators

Forward Iterator: that can only move forward through the container Bidirectional Iterator: can move backward as well as forward Random Access Iterator: in addition to moving forward and backward, can jump to an arbitrary location

STL Example

Example: vector class in STL

Think of vectors as smart arrays. They manage storage allocation for you, expanding and contracting the size of the vector as you insert or erase data. Use vectors much like arrays, accessing elements with the [] operator. Such random access is very fast with vectors. Its also fast to add (or push) a new data item onto the end (the back) of the vector. When this happens, the vectors size is automatically increased to hold the new item.

vector STL Member Functions

push_back()
swap()

empty()
back()

pop_back()
size()

Overloaded operator[]

vector STL use of Member Functions


#include <iostream> #include <vector> void main() { vector<int> v; //create a vector of int v.push_back(10); //put values at end of array v.push_back(11); v.push_back(12); v.push_back(13); v[0] = 20; v[3] = 23; for(int j=0; j<v.size(); j++) cout << v*j+ << ; cout << endl; }

vector STL use of Member Functions


#include <iostream> #include <vector> void main() { double arr[] = { 1.1, 2.2, 3.3, 4.4 }; vector<double> v1(arr, arr+4); vector<double> v2(4); //empty vector of size 4 v1.swap(v2); //swap contents of v1 and v2 while( !v2.empty() ) //until vector is empty, { cout << v2.back() << ; //display the last element v2.pop_back(); //remove the last element } cout << endl; }

vector STL use of Member Functions


#include <iostream> #include <vector> void main() { int arr[] = { 100, 110, 120, 130 }; vector<int> v(arr, arr+4); cout << \nBefore insertion: ; for(int j=0; j<v.size(); j++) cout << v*j+ << ; v.insert( v.begin()+2, 115); cout << \nAfter insertion: ; for(j=0; j<v.size(); j++) cout << v*j+ << ; v.erase( v.begin()+2 ); cout << \nAfter erasure: ; for(j=0; j<v.size(); j++) cout << v*j+ << ; cout << endl; }

//an array of ints //initialize vector to array //display all elements //insert 115 at element 2

//display all elements


//erase element 2 //display all elements

Вам также может понравиться