Title: Generic Programming
1Generic Programming
- Use class function templates
- Outline generic programming ideas
- Need to constrain template parameters
- Concepts
- Lifting
- Lift an algorithm
- Relate STL to Generic Programming
- http//www.sgi.com/tech/stl/
2Function Templates
- template ltclass IIterator, class Tgt
- bool contains(IIterator first, IIterator
beyond,const T v) -
- while ((first ! beyond) (first ! v))
- first
- return (first ! beyond)
-
- int array2
- array0 2
- array1 3
- if (contains(array,array2, 3))
- cout ltlt "3 found\n"
-
No need to instantiate. Compiler automatically
finds the template function and matches the types.
Compiler may use our template, but will choose a
more specific option if it exists
e.g. bool contains( int f, int s, int
val) or template ltclass Tgt bool contains (T f,
Tf, T val)
3Class Templates
Any unique name
- template lttypename Tgt class node
- public
- T data
- nodeltTgt next
- node()
- node(T data, node next NULL)
-
- template lttypename LTgt class list // list of
nodes - nodeltLTgt head
-
-
- listltintgt myList
Why not data 0 to define the default
constructor in one routine?
What does this do?
Any unique name
Could T be reused?
Have to specialise the node template
Create a list to contain integers
Must provide a type.
Template instantiation or specialisation
4Non-Type Parameters
- template lttypename T, int SIZEgt
- class ArrayContainer // a container with maximum
size - public
- T bodySIZE
- int currentLimit //a flexible limit must
be lt size - ArrayContainer(int s SIZE)
- if (s gt SIZE)
- s SIZE
- currentLimit s
-
-
-
- ArrayContainerltint, 2gt array
Is this the best way of handling this error?
5What about header files?
- Templates are used at compile time
- Compiler needs the template definition
- Cant just provide header file
- Bad news if youre a library provider
- C standard provides export
- Allows separation of header body
- Compiler needs a representation of body
6Generic Programming
Using Templates
- STL uses Generic Programming
- Represent efficient algorithms abstractly
- Apply to wide range of data abstractions
- Find general constraints
- Allow the algorithms to perform efficiently
- Maximise flexibility
- Belief / Experience
- Many algorithms have the same constraints
- Many implementations of these constraints
So, capturing constraints is useful
Can reuse algorithms
7Generic Programming
- Use templates to generalise algorithms
- Keep efficiency
- Instantiated template is as efficient hand-code
- If needed can provide several generic forms
- A generally applicable one
- More efficient ones for special cases
- Compiler picks most efficient if appropriate
- Need precise characterizations of the domain for
which each is appropriate
8Finding Abstractions Lifting
- Lifting generalises concrete algorithms
- Use templates to replace data types
- Identify constraints on replacement types
- Key question
- What are the essential constraints on data types
for a correct and efficient algorithm? - Include constraints in documentation
- Some will be checked by compiler. E.g.
- T x // T must have ltlt
- cout ltlt x // flagged at compiler-time
- Some cant be. E.g.
- x.insert(y) // must take linear time
9Lifting How to do it
- Start with multiple implementations of an
algorithm - Look for common features
- Produce generic algorithm
- By merging versions of an algorithm
- Cover many concrete implementations
- Make as abstract as possible
- Maximum reusability
- But efficient, concrete implementations
- Define data abstractions
- Constraints on parameters to template.
10Lifting Example
- Two implementations of summation
Replace int and float with a type parameter T.
11Lifted Generic Algorithm
- templatelttypename Tgt
- T sum(T array, int n)
- T result 0
- for (int i 0 i lt n i)
- result result arrayi
- return result
-
- templatelttypename Tgt "for all types T
- Will any type work?
- What operations must the type T support?
- Look at operations in the function using T
12Containers
- A container class provides
- a member type, iterator,
- Models (satisfies) the Iterator concept
- two member functions
- begin() returns the start iterator of the
sequence - end() returns the iterator referring to the
past-the-end position of the sequence. - E.g.
- template ltclass Tgt class list
- void push_back( const T t) // append t to
list. - typedef ... iterator // details of type
omitted () - iterator begin()
- iterator end()
-
13Defining ranges using Iterators
- Sequences of items are specified by a range
first,beyond) of two iterators. -
- Defines a sequence of iterator values
- starting with the iterator, first
- advancing first until beyond is reached
- Does not include beyond
- beyond is the past-the-end position
Inclusive limit
Non-inclusive limit
14contains() Find an item
- Dont write for a particular container
- Write for iterators
- E.g. a generic contains() function
- true if value is in range first,beyond).
- template ltclass IIterator, class Tgt
- bool contains(IIterator first,IIterator beyond,
const T v) -
- while ((first ! beyond) (first ! v))
- first
- return (first ! beyond)
15Using contains with pointers
- Works with pointers referring to a array.
- C-pointers model a random access iterator
- more general than an input iterator
- int a100
- // ... initialize elements of a.
- bool found contains( a, a100, 42)
- Searching part of an array.
- bool in_first_half contains( a, a50, 42)
- bool in_third_quarter contains( a50, a75, 4)
Which means can be used if a random access
iterator is expected.
model is a fancy way of saying satisfy the
constraints of
16Using contains() with iterators
- contains() with a list class template
- listltintgt ls
- // ... insert some elements into ls.
- bool found contains( ls.begin(), ls.end(),42)
17Concepts
- Represent patterns in the requirements.
- Often the same set of requirements are required
by several different algorithms. - Describe logical abstractions in the domain
- A type satisfying the constraints models the
concept - Generic Programming gives a generic, reusable
implementation, and a better understanding of the
problem domain.
18Concepts 2
- A set of requirements comprising
- Valid Expressions
- C expressions that must compile successfully
- Associated Types
- Used in the valid expressions.
- Defined by
- typedefs nested within a class definition
- a traits class.
- Invariants
- run-time conditions that must be true
- Complexity Guarantees
- limits on duration or resources of a valid
expression - Refinement
- A concept extending the requirements of another
19Example memcpy()
- void memcpy(void dest, const void src, size_t
n) -
- const char first (const char)src
- const char last ((const char)src) n
- char result (char)dest
- while (first ! last)
- dest first
- return dest
20Generalising memcpy() iterators
- Using void lets the function copy any array
- What if the data is in a linked list?
- Generalize to any sequence of elements?
- The minimal requirements are to
- traverse the sequence using some sort of pointer
- access elements pointed to
- write the elements to the destination
- compare pointers to know when to stop.
- Relevant concepts
- Input Iterator read only
- Output Iterator write only
21Memcpy() as a function template
- Types replacing template parameters
- Must model Input Iterator Output Iterator
- i.e. provide the relevant operators, etc.
- A reusable Memcpy() function
- template lttypename IIterator, typename OIteratorgt
- OIterator copy(IIterator f, IIterator l,
OIterator dest) - OIterator result dest
- while (f ! l)
- dest f
- return dest
-
The programmer must ensure these types are
instantiated to something obeying these
constraints. The compiler can only check some of
the constraints automatically.
22Summary
- Generic programming uses templates
- Generalise algorithm using template classes
- Generalise data types
- Must have algorithm-dependant operations
- Use concepts to define constraints
- Algorithmic design rather than OO
- STL illustrates generic programming