Title: Generic Programming vs' OOP
1Generic Programming vs. OOP
- Lift a function to a generic function
- Recognise constraints
- Explain how traits are used
- Explain how a template is selected
- Compiler uses the most specific match
- State generic criticisms of OOP
- http//www.sgi.com/tech/stl/
2Concept
- A frequently used set of requirements.
- Used by several different algorithms.
- Describes a logical abstraction
- Container, iterator, assignable
- A type can model the concept
- If it satisfies the constraints
- E.g. int models a random access iterator
- A Concept is like an abstract class
- Defines behaviour
- But not currently built into the language
- Not properly supported by compiler
3Lifting Example memcpy()
- int memcpy(int dest, const int source, int
size) -
- const int first source
- const int last source size
- char result (char)dest
- while (first ! last)
- dest first
- return result
-
- integer by integer copy
- Regions defined by pointer size
- Requirements
- can compare pointers
- can dereference pointers (for read and write)
- can increment pointers
- can add an item of type int to a pointer
4Generalising memcpy() iterators
- Using void lets the function copy any array
- But what if the data is in a linked list?
- Can we generalize to any sequence of elements?
- The minimal requirements are to
- Traverse the sequence using some sort of pointer
- Access elements pointed to (input)
- Write the elements to the destination (output)
- Compare pointers to know when to stop.
- Relevant concepts
- Input Iterator read only
- Output Iterator write only
5Memcpy() as a function template
- template parameters constrained
- Input Output Iterator concepts
- A reusable Memcpy() function
- template lttypename IIterator, typename OIteratorgt
- OIterator memcpy(IIterator f, IIterator l,
OIterator dst) - OIterator result dst
- while (f ! l)
- dst f
- return result
The programmer must ensure these types are
instantiated to something obeying these
constraints. The compiler can only check some
constraints automatically.
e.g. cant check complexity constraints
6Traits Class
- Helper class templates
- Information on a compile-time entity
- Consistent format
- E.g. stditerator_traitsltTgt
- template ltclass Iteratorgt
- struct iterator_traits
- typedef ... iterator_category
- typedef ... value_type
- typedef ... difference_type
- typedef ... pointer
- typedef ... reference
-
- An introduction to C Traits (http//thad.notagot
h.org/cpptraits_intro/)
can help select more efficient algorithms dependin
g on the iterator's capabilities
the type the iterator "points at.
7Using Traits
Concepts
- sum() uses iterator_traits to find value_type.
- // Requirements IteratorltIgt, Addableltvalue_typegt,
- // Assignableltvalue_typegt, CopyConstructibleltvalue
_typegt - // 0 assignable to value_type
- templatelttypename Igt
- iterator_traitsltIgtvalue_type sum(I start, I
end) - typename iterator_traitsltIgtvalue_type init
0 - for (I pos start pos ! end pos)
- init init pos
- return init
value_type items must have operator What if it
only has ? Could say init pos Whats the
problem with this?
8Traits take it or leave it
- traits templates are non-intrusive
- Can associate information with any type
- built-in types
- types defined in third-party libraries,
- Can define for a particular type by specializing
the traits template. - E.g stdnumeric_limitsltTgt
- Provides constants describing the range and
capabilities of numeric types.
9Using Traits average of an array
- templatelttypename Tgt
- struct average_traits
- typedef T average_type
-
- template ltint size, typename Tgt
- average_traitsltTgtaverage_type average(T
data) - typename average_traitsltTgtaverage_type
total0 - int num 0
- const int lim size / sizeof(T)
- while(num lt lim)
- total datanum
-
- return total/num
10Using Traits average 2
templateltgt struct average_traitsltintgt typedef
float average_type
The mean of 1.9 2.9 3.9 4.9 is 3.4 The mean of
1 2 3 4 is 2 Press any key to continue
The mean of 1.9 2.9 3.9 4.9 is 3.4 The mean of
1 2 3 4 is 2.5 Press any key to continue
- int main(int argc, char argv)
-
- double ddata 1.9, 2.9, 3.9, 4.9
- double mean averageltsizeof(ddata)gt(ddata
) -
- int idata 1, 2, 3, 4
- mean averageltsizeof(idata)gt(idata)
-
11Specifying traits
Specialisation is a useful technique, that can be
used to provide a more efficient implementation
of a general algorithm for a particular type. It
can be used with function templates as well as
class templates.
average_traitsltdoublegt
average_traitsltintgt
- Specialization links traits with a type
- templatelttypename Tgt
- struct average_traits
- typedef T average_type
-
- templateltgt
- struct average_traitsltintgt
- typedef double average_type
-
average_traitsltdoublegt
This is a specialisation of the average_traits
template
average_traitsltintgt
Picked because it is more specific
12Using Traits stdadvance()
- stdadvance()
- increments an iterator n times.
- Optimizations depend on iterator type
- Random access use i n
- Very efficient constant time.
- Other iterators must be stepped (so linear)
- Bidirectional
- n can be negative
- select increment or decrement
13Using Traits 2 Tag Dispatching
- Dispatching
- Selecting one operation from many
- Tag
- A property used in dispatching.
- advance()
- gets iterator_category from iterator_traits
- call overloaded dispatch()
- selected automatically by the compiler
- based on the iterator_category tag
14Default dispatch
- namespace std
- struct ii_tag
- struct bidi_tag
- struct ra_tag
- namespace detail
- template ltclass IIterator, class Steps gt
- void dispatch(IIterator i, Steps n, ii_tag)
- while (n--) i
-
Ive abbreviated these Names from the STL
This parameter isnt used in the function its
just a cunning way to force the compiler to
select the appropriate version of dispatch
15BidirectionalIterator dispatch
Compiler will pick this version of dispatch if
the third parameter is of this type
- template ltclass BidiIterator, class Stepsgt
- void dispatch(BidiIterator i, Steps n,
bidi_tag) - if (n gt 0)
- while (n--) i
- else
- while (n) --i
Need to know if the direction is positive or
negative and handle properly
16RandomAccessIterator dispatch
- template ltclass RAIterator, class Stepsgt
- void dispatch(RAIterator i, Steps n, ra_tag)
- i n
-
- //End namespace detail
Random Access Iterator Efficient constant time
17Using Traits advance
A dummy variable, only its type is important
- template ltclass IIter, class Stepsgt
- void advance(IIterator i, Steps n)
- typename iterator_traitsltIItergtiterator_catego
ry id - detaildispatch(i, n, id)
-
- //End namespace std
Tells the compiler iterator_category is a
type. It could be a static variable
The compiler will optimise away the dummy variable
Compiler will pick appropriate version of
dispatch based on type of id
18Defining traits
- Could define trait properties inside the
described class - Only works for new classes
- What about pointers? valid iterator need
traits - STL use a template parameterized by iterator
- template ltclass Iteratorgt
- struct iterator_traits
- typedef typename Iteratorvalue_type
value_type - // ...
-
- The value type is
- iterator_traitslt iteratorltsetgt gtvalue_type.
The space is vital why?
Compilers lexical analyser will recognise it as
gtgt operator generate error
19Defining traits by specialisation
- For pointers
- create a specialized version
- template ltclass Tgt
- struct iterator_traitsltTgt
- typedef T value_type
- // ...
-
- Use specialisation for C-pointer
- e.g. int,
- iterator_traitslt int gtvalue_type.
20OOP unsound?
- OOP
- starts with classes.
- analyses the world using interfaces that vary on
a single type - Real problems need families of interfaces that
span multiple types. - Programming starts with algorithms
- Understand the algorithm
- Then design an appropriate interface
http//www.stlport.org/resources/StepanovUSA.html
An Interview with A. Stepanov by Graziano Lo
Russo
21What OO cant do
- You can't write a generic max()
- two arguments and result of same type
- template ltclass Ordered gt
- inline const Ordered max(const Ordered x,
const Ordered y) - return x lt y ? y x
-
- If OO cant implement max or swap or linear
search, what is it good for? - Why C is not just an Object-Oriented
Programming Language (1995) Bjarne Stroustrup
22Summary
- Lifting
- Modify generalise an algorithm
- Minimise constraints
- Template Specialisation
- Compiler picks most specific template
- Efficiency with flexibility
- Traits
- Programming technique
- Separate class
- Has compile-time info about a data type