Title: ADT Implementations: Templates and Standard Containers
1ADT Implementations Templates and Standard
Containers
2Contents
- Function Genericity overloading and templates
- Class Genericity templates
- The vector Container
- Iterators
3Function Genericity Overloading and Templates
- Initially code was reusable by encapsulating it
within functions - Example lines of code to swap values stored in
two variables - Instead of rewriting those 3 lines
- Place in a functionvoid swap (int first, int
second) int temp first first second
second temp - Then call swap(x,y)
4Function Genericity Overloading and Templates
- To swap variables of different types, write
another function - Overloading allows functions to have same name
- Signatures (types and numbers of parameters) keep
them unique to the compiler
- Problem this could lead to a library of swap
functions - One function for each standard type
- Compiler chooses which to use from signature
- But What about user-defined types?
5Function Templates
- In overloading, note how similar the 3 swap()
function in p.449-p450 - Difference the place where the type is specified
- Question can we pass the type somehow?
- Yes! You can! Templates make this possible
- Declare functions that receive both data and
types via parameter - Thus, codes become more generic
- Easier to reuse
6Template Mechanism
- Declare a type parameter (or type placeholder)
- Use it in the function instead of a specific type
- This requires a different kind of parameter list
void swap(______ first, ______ second)
________ temp first first second
second temp
7Template Mechanism (p.454)
- template is a C keyword
- Specify that what follows is
- A pattern for a function
- NOT a function definition
- Normal parameters within function parentheses
- Type parameters within template brackets (ltgt)
8Template Mechanism
- Attention A function template cannot be split
across files - Specification and implementation must be in the
same file - A function template is a pattern
- Describes how specific functions are constructed
- Constructed based on the actual type
(instantiation) - Type parameter said to be bound to the actual
type passed to it for each instantiation
9Template Mechanism
- Each of the type parameters must appear at least
once in parameter list of the function - compiler uses only types of the arguments in the
call - thus determines what types to bind to the type
parameters
10Function Template
- template lttypename ElementTypegt
- void Swap (ElementType first,
ElementType second) - ElementType hold first
- first second
- second hold
11Function Template
- template lttypename ElementTypegt
- void Swap (ElementType first,
ElementType second) - Originally, the keyword class was used instead of
typename in a type-parameter list. - Use class and typename interchangeably
12Function Template
- lttypename ElementTypegt names ElementType as a
type parameter - The type will be determined
- by the compiler
- from the type of the arguments passed
- when Swap() is called.
13General Form of Template
- template lttypename TypeParamgt FunctionD
efinition - or template ltclass TypeParamgt FunctionDefinition
- where
- TypeParam is a type-parameter (placeholder)
naming - the "generic" type of value(s) on which the
function operates - FunctionDefinition is the definition of the
function, using type TypeParam.
14Template Instantiation
- In and of itself, the template does nothing
- When the complier encounters a template
- Store the template
- Doesnt generate any machine instructions
- Later, when it encounters a call to swap()
- E.g., swap(int1, int2)
- Generate a integer instance of swap()
- Another example in p.455, Fig. 9.2
15Class Template
How did we create a new version of a stack for a
different type of element?
- Recall our Stack class
- const int STACK_CAPACITY 128
- typedef int StackElement
- class Stack
-
- / Function Members /
- public
- . . .
- / Data Members /
- private
- StackElement myArraySTACK_CAPACITY
- int myTop
16Whats wrong with typedef?
- To change the meaning of StackElement
- Merely change the type following typedef
- Problems
- Changes the header file
- Any program that uses this must be recompiled
- A name declared using typedef can have only one
meaning. - What if we need two stacks of different types in
the same program? - cannot overload like functions (same number,
type, and order of parameters) ? two classes with
two different names!!
17Class Template
- Use a class template
- the class is parameterized
- it receives the type of data stored in the class
- via a parameter (like function templates).
- Recall
- const int STACK_CAPACITY 128
- __________________________________
- class Stack/ Function Members
/public . . ./ Data Members
/private StackElement myArraySTACK_CAPAC
ITY int myTop
18General From of Class Template Declaration
- template lttypename TypeParam gt or
- template ltclass TypeParamgt class SomeClass
// ... members of SomeClass ... - More than one type parameter may be
specifiedtemplate lttypename TypeParam1,...,
typename TypeParamngtclass SomeClass //
... members of SomeClass ...
19Instantiating Class Templates
- Instantiate it by using declaration of
form ClassNameltTypegt object - Passes Type as an argument to the class template
definition. - Examples
- Stackltintgt intSt
- Stackltstringgt stringSt
- Compiler will generate two distinct definitions
of Stack - two instances
- one for ints and one for strings.
20Rules for Class Templates, p.460-461
- Definitions of member functions outside class
declaration must be function templates. - All uses of class name as a type must be
parameterized. - Member functions must be defined in the same file
as the class declaration.
21Applying the rules to our Stack Class
- Apply Rule 1
- Each member functions definition preceded
bytemplate lttypename StackElementgt
22Applying the rules to our Stack Class
- Apply Rule 2
- The class name Stack preceding the scope operator
() is used as the name of a type - must therefore be parameterized.
- template lttypename StackElementgtvoid
StackltStackElementgtpush(const StackElement
value) - / ... body of push() ... /
- Apply Rule 3 specification, implementation in
same file
23Alternative Version of Stack Class Template
- Note that templates may have more than one type
parameter - May also have ordinary value parameters
- See p.472 for example
24Implementing Queue Class
- template lttypename DataTypegt
- class Queue
- private class Node public
- DataType data
- Node next
- Node(DataType d, Node pNULL)
data(d), next(p) -
- typedef Node NodePtr
- NodePtr myFront
- NodePtr myBack
- public
-
25Template Review
- Code Reuses
- Code encapsulation by function
- Overloading functions
- templates
- Function template pattern
- Class template pattern
- 3 rules
26STL (Standard Template Library)
- A library of class and function templates
- Components
- Containers
- Generic "off-the-shelf" class templates for
storing collections of data - Algorithms
- Generic "off-the-shelf" function templates for
operating on containers - Iterators
- Generalized "smart" pointers that allow
algorithms to operate on almost any container
(access container elements)
27STLs 10 Containers, p474
- Kind of Container STL Containers
- Sequential deque, list, vector
- Associative map, multimap,
- multiset, set
- Adapters priority_queue,
- queue, stack
- Non-STL bitset, valarray,
- string
28The vector Container
- A type-independent pattern for an array class
(dynamic array-based) - capacity can expand
- self contained
- Declaration
- template lttypename Tgt
- class vector
- public . . .private T myArray
-
29The vector Container
- Constructors
- vectorltTgt v, // empty vector
- v1(100), // 100 elements of type T
- v2(100, val), // 100 copies of val
- v3(fptr,lptr) // contains copies of
- // elements in memory
// locations fptr to lptr - Exercises? Examples?
30vector Operations
- Information about a vector's contents
- v.size()
- v.empty()
- v.capacity()//expand by doubling its size
- v.reserve()//grow its capacity to para
- Adding, removing, accessing elements
- v.push_back()
- v.pop_back()
- v.front()//return a reference to vs first item
- v.back()
31vector Operations
- Assignmentv1 v2
- Swappingv1.swap(v2)
- Relational operators
- implies element by element equality
- less than lt behaves like string comparison
32Exercises
- vector v //right or wrong? Why?
-
- vectorltdoublegt vcout ltlt v.capacity() ltlt " "
ltlt v.size() ltlt endl - vectorltintgt v(3) cout ltlt v.capacity() ltlt "
" ltlt v.size() ltlt endl - vectorltintgt v(4, 5) cout ltlt v.capacity() ltlt
" " ltlt v.size() ltlt endl - vectorltintgt vv.push_back(9) v.push_back(8)
v.push_back(7)cout ltlt v.capacity() ltlt " " ltlt
v.front() ltlt endl
33Iterators
- Note from table 9.3 that a subscript operator is
provided, p478 - BUT this is not a generic way to access
container elements - STL provides objects called iterators
- can point at an element
- can access the value within that element
- can move from one element to another
- They are independent of any particular container
thus a generic mechanism
34Iterators
- Given a vector which has had values placed in the
first 4 locations - v.begin() will return the iterator value for the
first slot, - v.end() for the next empty slot
vectorltintgt v
35Iterators
- Each STL container declares an iterator type
- can be used to define iterator objects
- To declare an iterator object
- the identifier iterator must be preceded by
- name of container
- scope operator
- Examplevectorltintgtiterator vecIter v.begin()
36Iterators
- Basic operators that can be applied to iterators
- increment operator
- decrement operator --
- dereferencing operator
- Assignment
- Addition, subtraction , -, , -vecIter n
returns iterator positioned n elements away - Subscript operator vecItern returns
reference to nth element from current position
37Iterators
- Contrast use of subscript vs. use of iterator
ostream operatorltlt(ostream out, const
vectorltdoublegt v) for (int i 0 i lt
v.size() i) out ltlt vi ltlt " " return
out
38Exercise
- vectorltdoublegt v
- for (int i2 ilt5 i) v.push_back(1.1 i)
- cout ltlt v.capacity() ltlt ltlt v.size() ltlt endl
- vectorltdoublegtiterator it, it1, it2
- for (it v.begin() it ! v.end() it) cout
ltlt it ltlt - cout ltlt endl
- it1 v.begin() it2 v.end()
- it1 8.8 (it2-1) 9.9
- for (it v.begin() it ! v.end() it) cout
ltlt it ltlt - cout ltlt endl
- it1 2 it2--
- cout ltlt it11 ltlt ltlt it2-1 ltlt endl
39Lecture Review
- Three ways to reuse code
- Encapsulation code within functions
- Function overloading
- Function templates
- Function template is a pattern from which a
specific function is constructed - Class template is a pattern from which a specific
function is constructed - 3 rules governing building of class templates
- The limitation of typedef
40Lecture Review
- STL containers provide generic and efficient data
structures for implementing ADTs - STL algorithms provide generic and efficient
operations for implementing ADTs - Iterators provide a generic way to access
elements in a container - Know containers such as vector
41Questions Reading
- Any Questions?
- Reading Chapter 10.4