Elements are always copied when they are put into a container

Slides:



Advertisements
Similar presentations
. STL: C++ Standard Library (continued). STL Iterators u Iterators are allow to traverse sequences u Methods  operator*  operator->  operator++, and.
Advertisements

TEMPLATES Lecture Presented By SHERY KHAN Object Orienting Programming.
C++ Sets and Multisets Set containers automatically sort their elements automatically. Multisets allow duplication of elements whereas sets do not. Usually,
. STL: C++ Standard Library. Main Ideas u General purpose: generic data structures & algorithms, templates u Flexibility: Allows for many combinations.
OOP Etgar 2008 – Recitation 101 Object Oriented Programming Etgar 2008 Recitation 10.
C++ Programming: Program Design Including Data Structures, Second Edition Chapter 22: Standard Template Library (STL)
CMSC 202 Lesson 24 Iterators and STL Containers. Warmup Write the class definition for the templated Bag class – A bag has: Random insertion Random removal.
Data Structures Using C++1 Chapter 13 Standard Template Library (STL) II.
CSE 332: C++ templates and generic programming I Motivation for Generic Programming in C++ We’ve looked at procedural programming –Reuse of code by packaging.
Lecture 11 Standard Template Library Stacks, Queue, and Deque Lists Iterators Sets Maps.
Templates and the STL.
CSE 332: C++ Algorithms II From Last Time: Search with Generic Iterators Third generalization: separate iterator type parameter We arrive at the find algorithm.
CSIS 123A Lecture 12 Templates. Introduction  C++ templates  Allow very ‘general’ definitions for functions and classes  Type names are ‘parameters’
Spring 2010 Advanced Programming Section 1-STL Computer Engineering Department Faculty of Engineering Cairo University Advanced Programming Spring 2010.
Dr. Yingwu Zhu STL Vector and Iterators. STL (Standard Template Library) 6:14:43 AM 2 A library of class and function templates Components: 1. Containers:
STL Standard Template Library ● Good reference book: – The C++ Standard Library ● A Tutorial and Reference ● by Nicolai M. Josuttis ● 1999 – Addison Wesley.
Data Structures Using C++ 2E
CNS  Sequences  vector,deque,list,(string),forward_list  Container Adapters  queue, stack, priority_queue  Associative Containers  set, unordered_set.
DATA STRUCTURES AND ALGORITHMS Lecture Notes 12 Prepared by İnanç TAHRALI.
CSE 332: C++ Type Programming: Associated Types, Typedefs and Traits A General Look at Type Programming in C++ Associated types (the idea) –Let you associate.
CSE 332: C++ STL algorithms C++ STL Algorithms Generic algorithms –Apply to a wide range of types E.g., sorting integers (long) or intervals (long, long)‏
Generic Programming Using the C++ Standard Template Library.
Data Structures Using C++ 2E Chapter 13 Standard Template Library (STL) II.
STL multimap Container. STL multimaps multimaps are associative containers –Link a key to a value –AKA: Hashtables, Associative Arrays –A multimap allows.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 22: Standard Template Library (STL)
CSE 332: C++ STL containers Review: C++ Standard Template Library (STL) The STL is a collection of related software elements –Containers Data structures:
Standard Template Library The Standard Template Library was recently added to standard C++. –The STL contains generic template classes. –The STL permits.
Lecture 8-3 : STL Algorithms. STL Algorithms The Standard Template Library not only contains container classes, but also algorithms that operate on sequence.
Lecture 11 Standard Template Library Lists Iterators Sets Maps.
A gentle introduction to the standard template library (STL) Some references:
Chapter 8 Writing Generic Functions. Objectives Understand the use of generic functions. Learn about the use of templates, their advantages and pitfalls.
CSCI  Sequence Containers – store sequences of values ◦ vector ◦ deque ◦ list  Associative Containers – use “keys” to access data rather than.
Main Index Contents 11 Main Index Contents Sets Defined by a key along with other data Sets Defined by a key along with other data Key-Value Data Key-Value.
Unit VI.  C++ templates are a powerful mechanism for code reuse, as they enable the programmer to write code (classes as well as functions) that behaves.
Object-Oriented Programming (OOP) Lecture No. 41
Lecture 36 OOP The STL Standard Template Library
Motivation for Generic Programming in C++
CS212: Object Oriented Analysis and Design
C++ Templates.
Exceptions, Templates, and the Standard Template Library (STL)
CSCE 210 Data Structures and Algorithms
C++ Standard Library.
Standard Template Library (STL)
Starting Out with C++ Early Objects Eighth Edition
Collections Intro What is the STL? Templates, collections, & iterators
Basic Data Structures.
Chapter 22: Standard Template Library (STL)
Associative Structures
Containers & Iterators
Containers, Iterators, Algorithms, Thrust
Recitation Outline C++ STL associative containers Examples
Hash Tables Chapter 12 discusses several ways of storing information in an array, and later searching for the information. Hash tables are a common.
Standard Version of Starting Out with C++, 4th Edition
Lists - I The List ADT.
Iterators and STL Containers
Exceptions, Templates, and the Standard Template Library (STL)
Lecture 8-2 : STL Iterators and Algorithms
Hash Tables Chapter 12 discusses several ways of storing information in an array, and later searching for the information. Hash tables are a common.
Lab4 problems More about templates Some STL
Standard Template Library
Lesson 25 Miscellaneous Topics
Computer Programming Dr. Deepak B Phatak Dr. Supratik Chakraborty
Collections Intro What is the STL? Templates, collections, & iterators
Standard Template Library
CS 144 Advanced C++ Programming April 25 Class Meeting
Standard C++ Library Part II.
An Introduction to STL.
SPL – PS1 Introduction to C++.
A dictionary lookup mechanism
Standard Template Library
Presentation transcript:

Elements are always copied when they are put into a container Elements are always copied when they are put into a container. So the following is ok: vector<string> v1; { string s1("foo"); v1.push_back(s1); // a copy of s1 goes into v1 } // s1 is deallocated cout << v1.back() << endl; // ok - retrieves copy of s1

Elements are returned from containers and iterators by reference: vector<string> v1; string s1("foo"); v1.push_back(s1); // a copy of s1 goes into v1 string &s2 = v1.back(); // v1.back returns a reference v1.pop_back(); cout << s2 << endl; // s2 references deallocated object In this example, s2 is a reference to an object owned by the container. When the object is popped from the container, s2 no longer references a valid object.

To avoid dangling references, you can make a copy of the reference returned by a container or iterator: vector<string> v1; string s1("foo"); v1.push_back(s1); // a copy of s1 goes into v1 string s2 = v1.back(); // copy v1.back() into s2 v1.pop_back(); cout << s2 << endl; // ok now, since s2 was a copy

Summary of container insertion and retrieval: vector<string> v1; string s1("foo"); v1.push_back(s1); // a copy of s1 goes into v1 string s2 = v1.back(); // copy v1.back() into s2 v1.pop_back(); cout << s2 << endl; // ok now, since s2 was a copy Summary of container insertion and retrieval: foo foo user passes reference container makes copy void push_back(T& x) user makes copy container returns reference T& back() foo container

Last lecture we covered: STL sequence containers (list, vector) STL iterators Today we’ll cover: STL associative containers (map, multimap, set, multiset) STL algorithms

But first, the pair template template<class T1, class T2> class pair { public: T1 first; T2 second; pair(T1& v1, T2& v2): first(v1), second(v2) {} }; That’s it. Example: #include <utility> using namespace std; pair<int, float> p1(5, 6.6); cout << p1.first << “ “ << p1.second;

Associative containers The canonical associative container: map (sometimes called a dictionary) A map maps keys to values. For instance, the following map maps keys of type string to values of type double: map<string, double> m1; m1["one"] = 1.0; m1["two"] = 2.0; m1["three"] = 3.0; cout << m1["two"] << endl; This prints: 2

(Notice that for strings, “one” < “three” < “two”) map<string, double> m1; m1["one"] = 1.0; m1["two"] = 2.0; m1["three"] = 3.0; maps support bidirectional iterators. The iterator for a map iterates over (key, value) pairs, in order sorted by the keys: map<string, double>::iterator i; for(i = m1.begin(); i != m1.end(); i++) { pair<string, double> x = *i; cout << x.first << ": " << x.second << endl; } This prints: one: 1 three: 3 two: 2 (Notice that for strings, “one” < “three” < “two”)

map operations template<class Key, class T> class map { ... public: iterator find(const Key& key); T& operator[] (const Key& key); void erase(iterator p); size_type size(); bool empty(); }

template<class Key, class T> class map { ... public: iterator find(const Key& key); T& operator[] (const Key& key); void erase(iterator p); size_type size(); bool empty(); } find looks up a key and returns an iterator pointing to the matching (key, value) pair. If the key is not found, find returns the end() iterator. map<string, double>::iterator i; i = m1.find("three"); if(i == m1.end()) {cout << "not found";} else {cout << i->first << ": " << i->second;}

template<class Key, class T> class map { ... public: iterator find(const Key& key); T& operator[] (const Key& key); void erase(iterator p); size_type size(); bool empty(); } The [] operator looks up a the value associated with a key, or associates a new value with a key: m1[“three”] = 3.0; cout << m1[“three”] << endl;

The [] operator automatically creates a value for a key if that key currently has no value. This is true even when [] is only being used for reading: map<string, double> m1; m1["one"] = 1.0; m1["two"] = 2.0; m1["three"] = 3.0; cout << m1["four"] << endl; This prints: Saying m1[“four”] automatically associates a default value with the key “four” in m1. For primitive types (ints, doubles, etc.), the default is 0. For classes, the default is based on the class’ no-argument constructor. Therefore, maps can only be used with classes that have a no-argument constructor.

size returns the number of elements in the map. template<class Key, class T> class map { ... public: iterator find(const Key& key); T& operator[] (const Key& key); void erase(iterator p); size_type size(); bool empty(); } erase removes an element from a map. Any iterators associated with this element become invalid. However, other iterators remain valid when elements are inserted into or removed from a map. size returns the number of elements in the map. empty returns (size() == 0)

Example: the following function prints the frequency of whitespace-separated words in a stream: void wordFrequency(istream& is) { map<string, int> m; // maps words to their frequency while(is.good() && !is.eof()) { string s; is >> s; // read in the next word m[s]++; // increment the word’s frequency count (this relies on } // the default value being 0) // print the results (the words and their counts): for(map<string, int>::iterator i = m.begin(); i != m.end(); i++) { cout << i->first << ": " << i->second << endl; }

Typical implementation of map: balanced binary tree Lower keys go to the left, higher keys go to the right: map<float, int> m1; m1[1.1] = 10; m1[1.5] = 20; m1[1.7] = 10; m1[2.1] = 20; m1[2.6] = 10; m1[3.3] = 20; m1[4.2] = 10; 2.1: 20 1.5: 20 3.3: 20 1.1: 10 1.7: 10 2.6: 10 4.2: 10

where the bool return value indicates whether t1 < t2. Example: To implement a binary tree, map needs to know how to order the keys. By default, map uses the < operator. We can also pass a pointer to a function to the map constructor to do the comparison (warning: if we do this, things get complicated fast). The function should have type bool (const T &t1, const T &t2) where the bool return value indicates whether t1 < t2. Example: bool stringLess(const string &s1, const string &s2) { return s1 < s2; }

So we can declare a map that uses stringLess as follows: bool stringLess(const string &s1, const string &s2) { return s1 < s2; } map takes a third template argument that specifies the type of the comparison function: template <class Key, class T, class Cmp> map { ... map(Cmp &cmp) {...} So we can declare a map that uses stringLess as follows: map<string, int, bool (*)(const string&, const string&)> m(&stringLess); This is a little on the complicated side.

Pointers to functions specify only code (not data) Pointers to functions specify only code (not data). A language that supported higher-order functions (which contain both code and data) would be more powerful here. C++ can imitate higher-order functions with a surprising hack: C++ allows classes to overload the function call operator: class StringLess { public: // overload function call operator: bool operator() (const string &s1, const string &s2) const { return s1 < s2; } };

Now we can use a StringLess object as if it were a function: class StringLess { public: bool operator() (const string &s1, const string &s2) const { return s1 < s2; } }; Now we can use a StringLess object as if it were a function: StringLess f; bool b = f(“hello”, “goodbye”); // looks like a function call An object with an overloaded function call operator is often called a function object.

We can use a function object as an argument to map’s constructor: class StringLess { public: bool operator() (const string &s1, const string &s2) const { return s1 < s2; } }; template <class Key, class T, class Cmp> map { ... map(Cmp &cmp) {...} We can use a function object as an argument to map’s constructor: map<string, int, StringLess> m(StringLess()); Notice that the type StringLess is passed as the Cmp parameter to the map template, so that map knows what type is being passed to its constructor.

And map will instantiate a StringLess object for us. class StringLess { public: bool operator() (const string &s1, const string &s2) const { return s1 < s2; } }; template <class Key, class T, class Cmp> map { ... map() {...} map(Cmp &cmp) {...} In fact, map has a default constructor that creates a function object based on Cmp’s default constructor. So we can simply say: map<string, int, StringLess> m; // use map’s default constructor And map will instantiate a StringLess object for us.

Finally, map also has a default template parameter: template <class Key, class T, class Cmp = less<Key> > map {...} less is a simple class that uses < to implement the function call operator: template<class T> class less { public: bool operator()(const T &t1, const T &t2) const {return t1 < t2; } }; So this default template parameter allows us to just write: map<string, int> m; // uses less<string> by default

So let’s summarize how the simple declaration works: map<string, int> m1; This declaration of m1: uses the default (no-argument) constructor of map<string,int>. which in turn uses the default template argument map<string,int> (which is less<string>) as a comparison function. map instantiates a less<string> object using less<string>’s default constructor. The less<string> overloaded function invocation operator in turn uses the overloaded < operator to compare strings. This is complicated, but it’s flexible and the defaults are convenient.

Various associative containers multimap maps each key to one or more values map maps each key to exactly one value 737-9924 737-9924 “Frank” “Frank” 790-0015 “Bob” “Bob” 737-6648 737-6648 set has keys, but no values multiset allows duplicate keys “Frank” “Frank” “Alice” “Frank” “Bob” “Bob” “Bob”

Generic algorithms Now we’ve seen containers and iterators. The final component in the standard template library is algorithms. containers - hold collections of objects iterators - iterate through a container’s elements algorithms - use iterators to implement sort, search, etc.

For instance, the sort algorithm works for any random access iterator: STL algorithms never refer to container classes directly. Instead, the algorithms make use of iterators. Since iterators are standardized into categories, this allows a single algorithm to work for any container that implements the appropriate category of iterator. For instance, the sort algorithm works for any random access iterator: template <class Ran> void sort(Ran first, Ran last); In this declaration, Ran is supposed to by the type of the random-access iterator, and first and last mark the beginning and end of the container to be sorted. input forward bidirectional random-access output

template <class Ran> void sort(Ran first, Ran last); Example: vector<float> v(10, 5.0); ... sort(v.begin(), v.end()); This version of sort uses the < operator to compare element types. Another version of sort takes a comparison function (which computes the less-than relation) as an argument: template <class Ran, class Cmp> void sort(Ran first, Ran last, Cmp cmp); cmp may be a pointer to a function, or it may be an object that overloads the () operator.

copy is a simple function that copies elements from one container to another: vector<float> v1; ... vector<float> v2(v1.size(), 0.0); copy(v1.begin(), v1.end(), v2.begin()); This copies all of v1’s elements into v2. To use copy, the destination container v2 must already have room for the elements that are copied into it. However, a special back_inserter iterator may be used to automatically increase the destination container’s size as elements are added: vector<float> v2; copy(v1.begin(), v1.end(), back_inserter(v2));

Surprisingly, STL algorithms can be used with ordinary arrays: float f[4]; f[0] = 2.3; f[1] = 1.2; f[2] = 4.5; f[3] = 3.4; sort(f, f + 4); This is because pointers into an array are perfectly good random-access iterators, since they define operations like ++, --, +, *, etc.

One limitation of basing algorithms on iterators instead of containers is that the algorithms cannot remove elements from a container. However, algorithms can swap elements around (as in sort), and this can be used to simulate removal. For instance, the remove function simply rearranges a container so that all the “removed” elements get moved to the back: 2 3 5 1 5 4 6 7 v1 remove(v1.begin(), v1.end(), 5); 2 3 1 4 6 7 5 5 v1

Many algorithms take pointers to functions or function objects as arguments. For instance, for_each takes two input iterators and calls a function for each element in the range specified by the iterators: template<class In, class Op> Op for_each(In first, In Last, Op f) { while(first != last) {f(*first); first++;} return f; } remove_if “removes” all elements (in a range specified by two forward iterators) that satisfy a predicate specified by a pointer to a function or function object: template<class For, class Pred> For remove_if(For first, For last, Pred p);

STL provides algorithms for a wide variety of tasks: nonmodifying sequence operations: for_each, find, count, search, ... modifying sequence operations: transform, copy, generate, rotate, remove, random_shuffle, ... sorted sequence operations: sort, binary_search, ... and many more (60 algorithms in all) STL algorithms promote programming at a higher level - you can program in terms of high-level operations over entire containers, rather than in terms of low-level iterations through containers.