STL Generic Programming to the extreme 1 TA

  • Slides: 37
Download presentation
STL Generic Programming to the extreme 1

STL Generic Programming to the extreme 1

TA 6 - Agenda �Associative containers �Function object (functor) �Iterators 2

TA 6 - Agenda �Associative containers �Function object (functor) �Iterators 2

Sorted associative containers �Elements are inserted in predefined order, such as ascending order �Supports

Sorted associative containers �Elements are inserted in predefined order, such as ascending order �Supports efficient retrieval of elements (values) based on keys �(Typical) Implementation: �red-black binary trees �hash-table (SGI extension, not standard) 3

Sorted Associative Containers �set �A set of unique, sorted, keys �map �Associate a value

Sorted Associative Containers �set �A set of unique, sorted, keys �map �Associate a value to key (associative array) �Unique, sorted, keys �multiset �multimap �Same, but allow multiple values 4

Why sorted? Finding keys in the container efficiently. � my. Set. find(key) //returns an

Why sorted? Finding keys in the container efficiently. � my. Set. find(key) //returns an iterator to the key � my. Set. count(key) � my. Set. erase(key) 5

Sorting – the C approach #include <stdlib. h> Array to be sorted Number of

Sorting – the C approach #include <stdlib. h> Array to be sorted Number of elements in array sizeof of each element in array void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); Pointer to the comparison function Returns an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second 6

Sorted Associative Containers & Order �Sorted Associative containers use the std: : less<T> as

Sorted Associative Containers & Order �Sorted Associative containers use the std: : less<T> as default order �We can control order by using our own comparison function �To understand this issue, we need to use… Function object / Functor 7

Function Object / Functor �Anything that “can be called as if a function” For

Function Object / Functor �Anything that “can be called as if a function” For example: �Pointer to function �A class that implements operator() 8

Example class c_str_less { public: bool operator()(const char* s 1, const char* s 2)

Example class c_str_less { public: bool operator()(const char* s 1, const char* s 2) const { return (strcmp(s 1, s 2) < 0); } }; c_str_less cmp; // declare an object if(cmp("aa", "ab")) … if(c_str_less()("a", "b")) 9 Creates a temporal object, and then calls operator()

Template comparator example template<typename T> class less { public: bool operator()(const T& lhs, const

Template comparator example template<typename T> class less { public: bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } }; less<int> cmp; // declare an object if(cmp(1, 2)) … if(less<int>()(1, 2)) 10

Comparator specialization Template<> class less <char*> { public: bool operator()(const char* s 1, const

Comparator specialization Template<> class less <char*> { public: bool operator()(const char* s 1, const char* s 2) { return (strcmp(s 1, s 2) < 0); } }; less<char*> cmp; // declare an object if(cmp("aa", "ab")) … if(less<char*>()("a", "b")) 11

Using Comparators // ascending order // uses operator < for comparison set<int> s 1;

Using Comparators // ascending order // uses operator < for comparison set<int> s 1; set<int, less<int>> s 1; // same // descending order // uses operator > for comparison set<int, greater<int>> s 2; 12

Why should we use classes as function objects? �So we get the “power” of

Why should we use classes as function objects? �So we get the “power” of classes. �Examples: �Inheritance. �To parameterize our functions in run time or in compile time. �To accumulate information. 13

Iterators �Iterators are a mean to traverse sequences �Main Methods �operator* �operator++ �Different types

Iterators �Iterators are a mean to traverse sequences �Main Methods �operator* �operator++ �Different types of iterators - to support read, write and random access �Containers define their own iterator types �Changing the container can invalidate the iterator �Other manipulations might invalidate iterator as well 14

Iterators and Containers Every STL container type defines: � Container: : value_type �Type of

Iterators and Containers Every STL container type defines: � Container: : value_type �Type of elements stored in container � Container: : iterator, for which defined: Container: : value_type operator*(); 15

16

16

Iterator Types �Output: write only and can write only once �Input: read many times

Iterator Types �Output: write only and can write only once �Input: read many times each item �Forward supports both read and write �Bi-directional support also decrement �Random supports random access (just like C pointer) 17

Iterators & Containers � Trivial iterators for: �a pointer to an object that is

Iterators & Containers � Trivial iterators for: �a pointer to an object that is not part of an array � Bidirectional iterators for: �list, map, set � Forward iterators for: �unordered map, unordered set � Random access iterators for: �vector, array � Input/output/forward iterators for: �istream, ostream 18

Iterators and Containers class Name. Of. Container {. . . typedef … iterator; //

Iterators and Containers class Name. Of. Container {. . . typedef … iterator; // iterator type of Name. Of. Container iterator begin(); // first element of Name. Of. Container iterator end(); // element after last of Name. Of. Container c; Name. Of. Container: : iterator i; for(i = c. begin(); i != c. end(); ++i) // do something with *i 19

Iterators and Containers �With templates: Name. Of. Container<. . . > c. . .

Iterators and Containers �With templates: Name. Of. Container<. . . > c. . . Name. Of. Container<. . . >: : iterator i; for(i= c. begin(); i!=c. end(); ++i) // do something that changes *i 20

const_iterators & Containers class Name. Of. Container {. . . typedef … const_iterator; const_iterator

const_iterators & Containers class Name. Of. Container {. . . typedef … const_iterator; const_iterator cbegin() const; const_iterator cend() const; // iterator type of Name. Of. Container // first element // element after last Name. Of. Container<. . . > c; Name. Of. Container<. . . >: : const_iterator it; for( it= c. cbegin(); it!=c. cend(); ++it) // do something that does not changes *it 21

Const iterators. . . iterator begin(); iterator end(); . . . const_iterator cbegin() const;

Const iterators. . . iterator begin(); iterator end(); . . . const_iterator cbegin() const; const_iterator cend() const; �Note that the begin() and end() methods that return regular iterator are not const methods. i. e: if we get a container by const reference we can't use these methods, we have to use the methods that return const_iterator. 22

Iterators & Sequence Containers Seq. Container. Name<. . . > c; Seq. Container. Name<.

Iterators & Sequence Containers Seq. Container. Name<. . . > c; Seq. Container. Name<. . . >: : iterator i, j; first, last are any type of input iterator c. insert(i, x) // insert x before i c. insert(i, first, last) // insert elements from the range [first, last) before i c. erase(i) // erase the element that i points to c. erase(i, j) // erase the elements in the range [i, j) 23

Iterators & other Containers �insert and erase has the same ideas for different containers,

Iterators & other Containers �insert and erase has the same ideas for different containers, except they keep the invariants of the specific container. �For example, a Sorted Associative Container will remain sorted after insertions and deletions. 24

Iterators and Assoc. Containers �What does c. insert(pos, x) does, when c is a

Iterators and Assoc. Containers �What does c. insert(pos, x) does, when c is a Unique Sorted Associative Container? �Inserts x into the set, using pos as a hint to where it will be inserted: hint regarding the place to start searching for the correct point of insertion. �If the hint is good, will reduce the insertion time from O(log(N)) to O(1) 25

Iterators and Assoc. Containers Additional set of operations: � iterator c: : find(key_type const&

Iterators and Assoc. Containers Additional set of operations: � iterator c: : find(key_type const& key) Returns iterator to first element with key � iterator c: : lower_bound(key_type const& key) Returns iterator to first element greater or equal to key � iterator c: : upper_bound(key_type const& key) Returns iterator to first element greater than key � end() if not found 26

Iterators & Map �Suppose we work with: map<string, int> dictionary; map<string, int>: : iterator

Iterators & Map �Suppose we work with: map<string, int> dictionary; map<string, int>: : iterator i; i = dictionary. begin(); �What is the type of *i ? �map<string, int>: : value_type 27

Iterators & Map �Ok – but what is it? map<const Key. Type, Value. Type>

Iterators & Map �Ok – but what is it? map<const Key. Type, Value. Type> keeps pairs: Key. Type key – “key” of entry Value. Type value – “value” of entry typedef pair<const Key, T> value_type; 28

pairs template< typename T 1, typename T 2> struct pair { typedef T 1

pairs template< typename T 1, typename T 2> struct pair { typedef T 1 first_type; typedef T 2 second_type; T 1 first; T 2 second; pair(const T 1& x, const T 2& y) : first(x), second(y) {}. . . }; 29

pairs � Part of the <utility> header � A template struct that stores 2

pairs � Part of the <utility> header � A template struct that stores 2 elements � Declaration: std: : pair<First. Type, Second. Type> � Has two fields: first and second std: : pair<int, char> my. Pair; my. Pair. first = 5; my. Pair. second = ‘a’; std: : pair<int, char> my. Pair(5, ’a’); my. Pair = std: : make_pair(5, ’a’); 30

Map template<typename Key, typename T, typename Cmp = less<Key>> class map { public: typedef

Map template<typename Key, typename T, typename Cmp = less<Key>> class map { public: typedef pair<const Key, T> value_type; typedef Key key_type; typedef T mapped_type; typedef Cmp key_compare; . . . }; 31

Using map iterator map<string, int> dict; . . . map<string, int>: : iterator i;

Using map iterator map<string, int> dict; . . . map<string, int>: : iterator i; for( i = dict. begin(); i != dict. end(); i++ ) { cout << i->first << " " << (*i). second << "n"; } 32

Map std: : map<Key. Type, Value. Type> my. Map; std: : map<char, int> my.

Map std: : map<Key. Type, Value. Type> my. Map; std: : map<char, int> my. Map; my. Map. insert(std: : make_pair(‘a’, 5)); my. Map[‘a’] = 7; //less efficient 33

Iterators’ Validity �When working with iterators, we have to remember that their validity can

Iterators’ Validity �When working with iterators, we have to remember that their validity can be changed �What’s wrong with this code? Container c; Container: : iterator i; for(i=c. begin(); i!=c. end(); ++i) if(f(*i)) // f is some test { c. erase(i); } �Invalidates i, thus we cannot “++” it 34

Iterators’ Validity Two cases: �list, set, map �i is not a legal iterator �vector

Iterators’ Validity Two cases: �list, set, map �i is not a legal iterator �vector �i (might) point to the element after �In either case, this is not what we want… 35

Iterator validity – second try. . . Container c; Container: : iterator i= c.

Iterator validity – second try. . . Container c; Container: : iterator i= c. begin(); while(i!=c. end()) { Container: : iterator j= i; ++i; if(f(*j)) // f is some test { c. erase(j); . . . } �Works for set, map, list, not vector or deque 36

How do you know? ! �Experience �Trial and error ; ) �http: //www. cplus.

How do you know? ! �Experience �Trial and error ; ) �http: //www. cplus. com/reference/stl/ �… 37