1
Templates and the STL
2
Template (generic) classes
the behavior of a container class does not depend of the kind of elements stored in the container
how can we create a generic (type independent) collection class using C++?
drawbacks of typedef have to change source code (recompile) for
each type can’t have multiple containers whose elements
are of different types an alternative: define a class template
template for creating a class
3
Function templates
template - a pattern or a mold functions/methods have data
parameters void f (int p1, float p2, Customer p3); argument provided when function is called
function templates also have type parameters
from one function template multiple actual functions can be generated (by the compiler)
allow a programmer to write "generic" functions - type independent
4
overloaded Swapvoid Swap(int & first, int & second) { int temp = first; first = second; second = temp;}
void Swap(string & first, string & second) { string temp = first; first = second; second = temp;}
differ only inthe type!
5
generic Swaptemplate <typename Item>void Swap(Item & first, Item & second) { Item temp = first; first = second; second = temp;}
1. Swap is a function template 2. Item is a type parameter3. keyword typename and class are interchangeable4. template function prototype and definition must be in the same file5. actual type substituted for Item must be "assignable"
6
Function instantiation
no object code is created from a function template
compiler generates object code for an actual function from a function template when needed when compiling a call to the function substitutes argument type for the type
parameter each call with a different argument type
results in object code for a new actual function
Swap(i, j); // i and j are ints - Item replaced by intSwap(s1, s2); // s1 and s2 are strings - Item replaced by stringetc.
7
Class templatesmake it possible to have several
objects of a container class, each of which holds a different type of element Stack of ints; Stack of strings; Stack
of ?declaration and implementation of a
template class have to be compiled together
template class implementation requires "messy" syntax
8
Class template for Stack
template < typename SE >class Stack{ public: - - - Stack ( ); void push (const SE & newElement); - - - SE top ( ) const; private: SE myArray[STACK_CAPACITY]; int myTop;};
template directive
Class name is Stack<SE>
9
declaring Stack<SE> objects
int main ( ){ Stack <int> samples; Stack <float> cost; Stack <string> names; Stack <customer> line; - - -
10
implementing a template class
cumbersome syntax needed each method is a template so is
preceded by the template directive class name is Stack<SE>
template <typename SE>Stack<SE>::Stack( ){ - - - -}
11
Compiling template classes
compiler cannot separately compile a template class compiler needs to know the actual type to
substitute compiler generates code when a template
class object is declared substitutes actual type for the type parameter needs access to the class implementation, not
just the class declaration compiler generates separate code for
each actual type substituted for the type parameter
12
Two solutions#include “stack” #include “stack.h”Client.cpp Client.cpp
stackstack.h
#include “stack.cpp”stack.cpp
client programe.g.; main client program
Stack templateclass declaration
implementation
Stack template class declaration followed by implementation
13
Standard Template Library (STL)
is a library of generic container classes which are both efficient and functional
C++ STL developed in early 90's at Hewlett Packard Laboratories Alex Stepanov and Meng Lee
became part of C++ standard in 1994 implementations available by late 90's
14
STL and Reuseability
STL is part of a movement toward libraries of reusable code function libraries (reusable algorithms) class libraries (reusable ADTs)
Java 1.2 introduced a library of Collection classes http://java.sun.com/docs/books/tutorial/
index.html data and algorithms packaged together (O-
O) STL separates data and algorithms
iterators allow algorithms to operate on data
15
STL components Containers
templates for classes which hold a collection of elements
Algorithms templates for functions which operate on a range of
elements from a container range is specified by iterators
Iterators give access to the elements in a container allow for movement from one element to another
Container classes AlgorithmsIterators
16
STL iterators iterators are "pointer-like" objects
provide a generic way to access the elements of any container class
many STL algorithms require iterators as arguments
some STL algorithms return an iterator each STL container class has an iterator
class associated with it vector<T>::iterator list<T>::iterator
stack<T> and queue<T> don't have iterators why?
17
Iterator categories
category determines available operations forward iterator
iter++ (increment) *iter (dereference) == and != (equality comparison)
bidirectional iterator adds iter-- (decrement)
random-access iterator adds iter[n] (constant time access to arbitrary
element) iter =+ n (increment n times)
18
STL Algorithms are function templates designed to operate
on a sequence of elements rather than methods
the sequence is designated by two iterators most container classes have the following
two methods begin( ) - returns an iterator positioned at
the container's first element
end( ) - returns an iterator positioned past the container's last element (past-the-end)
C.begin( ), C.end( ) specifies a sequence which contains all elements of the container C
19
STL Algorithmssome examples of STL algorithms
find (iter1, iter2, value) //returns an iterator
max_element (iter1, iter2) //returns an iterator
sort (iter1, iter2) //sorts using < for_each (iter1, iter2, F) //applies F to
every //item
see STL Programmer's Guide link on home page
20
STL container classes
Sequences - elements arranged in a linear order vector<T> - fast inserts only at the end; random
access list<T> - fast inserts anywhere; no random
access deque<T> - fast inserts at the beginning and the
end Adapters - provides a new interface (set of
operations) for one of the sequences stack<T> ex: stack<int> operands; queue<T> ex: queue<Customer> line; priority_queue<T>
Associative Containers - elements have key values set, map, multiset, multimap
21
vector<T> growable, self-contained, type-independent
array element type specified when a vector is
declared vector<double> numbers; vector<cashier> checkOutStations;
has a set of operations (methods) capacity increases when needed
some vectors vector<int> v1; (capacity is 0) vector<float> v2 (10); (capacity is 10; size is
10) vector<string> v3 (5, "C++"); (capacity is 5;
size is 5)
22
Some vector<T> methods
V.capacity( ) //size of array currently allocated V.size( ) //number of values V contains V.empty( ) //true iff V.size( ) is 0 V.reserve(n) //grow V so its capacity is n V.push_back(val) //add val at end of V V.pop_back( ) //erase V's last element V[i] //access element of V whose
index is i V.at(i) //access element of V whose
index is i
#include <iostream>#include <vector>using namespace std;bool Search(const vector<int> & V, int item);int main ( ) { vector<int> numbers; int number; while (cin >> number) { // enter <control> D to stop the loop if (Search(numbers, number)) cout << "Duplicate" << endl; else numbers.push_back(number); } cout << "number of unique values: " << numbers.size( );return 0;}bool Search(const vector<int> & V, int item) { int p = 0; while(p < V.size( ) ) if (item = = V[p]) // or V.at(p) return true; else p++; return false;}
#include <iostream>#include <vector>#include <algorithm>using namespace std;
int main ( ) { vector<int> numbers; int number; while (cin >> number) { if (find (numbers.begin ( ), numbers.end ( ), number) != numbers.end ( )) cout << "Duplicate" << endl; else numbers.push_back(number); } cout << "number of unique values: " << numbers.size( );return 0;}
#include <iostream>#include <vector>#include <algorithm>#include <cstdlib>using namespace std;void set (int & val); void display (int val); int main( ) { vector<int> A(5); for_each (A.begin ( ), A.end ( ), set); // would not work if vector<int> A; used for_each (A.begin ( ), A.end ( ), display); cout << endl; sort (A.begin ( ), A.end ( )); // operator< must be defined for A's element type for_each (A.begin ( ), A.end ( ), display); cout << endl; return 0;}void set (int & val) { val = rand ( );}void display (int val) { cout << " " << val;}
41 18467 6334 26500 1916941 6334 18467 19169 26500Press any key to continue
26
list<T> classanother STL container classused for storing a linear collection
of like itemscomparison to a vector?
linked list vs array is the underlying data structure
no indexing (iterators are bidirectional)
inserts and deletes anywhere are done in a constant amount of time
27
a list<T> data structure
2
------head
size
28
Basic list class methods
list( ); // construct an empty list
list (const list<T> & aList); // copy constructor
~list( ); // destructor list<T> operator= (const list<T> & aList);
// assignment operator bool empty( ); int size( );
29
Some more list methods
L.push_back(value) // append value to L L.push_front(value) // insert value at front of L L.insert(pos, value) // insert value into L at
// position indicated by iterator pos
L.front( ) // return L's first element L.back( ) // return L's last element L.begin( ) // return an iterator positioned at
start L.end( ) // return the"past the end"
iterator L.sort( ) // sort L's elements using <
Why not sort (L.begin( ), L.end( )); ?
#include <list>#include <iostream>using namespace std;int main ( ) { list<int>L; L.push_back (9); L.push_back (7); L.push_back (5); L.push_back (3); list<int>::iterator p; for (p = L.begin ( ); p != L.end ( ); p++)
cout << *p << endl; for (p = L.begin ( ); p != L.end ( ); p++)
(*p)++; for (p = L.begin ( ); p != L.end ( ); p++)
cout << *p << endl; return 0;}
975310864Press any key to continue