1 / 111

The Standard Template Library

The Standard Template Library. Some History. The Standard Template Library was developed by Alexander Stepanov and Meng Lee at Hewlett Packard, and is based on their research on Generic Programming . Significant contributions to these ideas came from David Musser. Some History.

gerry
Download Presentation

The Standard Template Library

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The Standard Template Library

  2. Some History The Standard Template Library was developed by Alexander Stepanov and Meng Lee at Hewlett Packard, and is based on their research on Generic Programming. Significant contributions to these ideas came from David Musser.

  3. Some History Recognizing the need for a set of re-usable components that implement commonly used data structures and algorithms, the C++ standards committee added the Standard Template Library to the standard C++ library.

  4. Almost all parts of the library are written as templates. Key components of the library are: Containers Iterators Algorithms

  5. Remember using vectors? A vector is actually part of the Standard Template Library. It is one of the container classes in the STL. Before we dive into the STL in detail, let’s review what we know about Vectors.

  6. Vectors A vector has many of the attributes of an array. In particular, elements in a vector appear as if they are stored sequentially, and can be accessed by an index into the vector. However, vectors are different from arrays because a vector will grow as required. Arrays are fixed in size.

  7. Declaring a Vector vector<int> scores; The type of data to be stored in the vector. The name of the vector object. The vector is initially empty.

  8. Declaring a Vector with an initial size. The size vector<int> scores(5); The type of data to be stored in the vector. The name of the vector object.

  9. Storing Data in a Vector vector<int> scores(5); 0 1 2 3 4

  10. Storing Data in a Vector vector<int> scores(5); 0 1 2 3 4 scores[3] = 127; 127

  11. Getting Data From a Vector vector<int> scores(5); 0 1 2 3 127 4 cout << scores[3] << endl;

  12. Growing a Vector vector<int> scores(5); 0 1 2 3 127 4 5 scores.push_back(119); 119

  13. Vectors Vectors store their elements in an internal dynamic array. You can access any element of a vector in constant time provided you know where the element is. Vectors provide good performance when adding or deleting elements at the end, but inserting or deleting in the middle is very expensive. This is because every element behind has to be moved to a new position. Insertion time is not constant! Vectors grow as required, but “growing” a vector is expensive, and invalidates all references, pointers and iterators for elements of the vector

  14. Inserting into a vector… 9 5 7 15 12 21 24

  15. Growing invalidates references Vector<int>::Iterator p ??? 5 7

  16. Vector Size Vectors never shrink. You can manage the size of a vector by calling c.reserve( size);

  17. vector<Elem> c; vector<Elem> c1(c2); vector<Elem> c(n); creates an empty vector. creates a copy of vector c2. creates a vector of n elements created by their default constructor. This also initializes base data types to 0 Vector Constructors

  18. Given a vector as our starting point, We will now discuss * Iterators * Generic Algorithms

  19. Iterators An iterator is an object that can be used to navigate over the elements stored in a container. An iterator represents a certain position in a container. An iterator can be thought of as a pointer, but it removes the programmer from worrying about the details typically required when dealing with pointers.

  20. ++ and -- moves the iterator to the next, or previous element both prefix and postfix operations are valid == and != used to see if two iterators point to the same location * used to dereference an iterator Operators on Iterators The following operators have been overloaded to manipulate iterators. They work on most container classes:

  21. Iterator Functions All container classes provide the same basic member functions that enable them to use iterators to navigate over their elements. The most important of these are: begin( ) Returns an iterator that represents the beginning element in the container end( ) Returns a sentinel that represents the end of the elements in the container. By convention, the end is the position behind the last element.

  22. Kinds of Iterators Input Output Forward Bidirectional Random

  23. Kinds of Iterators Input iterators are used to read an element from a container. An input iterator only moves in the forward direction. Input Output Forward Bidirectional Random

  24. Kinds of Iterators Input Output iterators are used to write an element into a container. An output iterator only moves in the forward direction. Output Forward Bidirectional Random

  25. Kinds of Iterators Input Output Forward iterators combines the capabilities of input and output iterators. Forward Bidirectional Random

  26. Kinds of Iterators Input Output Forward Bidirectional iterators combine the capability of a forward iterator with the ability to move backwards through the container. Bidirectional Random

  27. Kinds of Iterators Input Output Forward Bidirectional Bi-directional iterators combine the capabilities of a bidirectional iterator with the ability to directly access any element in a container. Random

  28. Different container classes support different kinds of iterators. Vector iterators are the most general, because all of the iterator operations work with a vector.

  29. Forward the ++ operator works on the iterator Bidirectional the ++ and –- operators work on the iterator Random ++, --, and [ ] operator work on the iterator

  30. Iterator Example

  31. Iterator Example // some #includes … int main( ) { const int SIZE = 4; vector<int> inums; 1st – create a vector

  32. Iterator Example // some #includes … int main( ) { const int SIZE = 4; vector<int> inums; for (int i = 0; i < SIZE; i++) inums.push_back(i); 1st – create a vector 2nd – fill it with values

  33. Iterator Example // some #includes … int main( ) { const int SIZE = 4; vector<int> inums; for (int i = 0; i < SIZE; i++) inums.push_back(i); vector<int>::iterator p; 1st – create a vector 2nd – fill it with values 3rd – create an iterator

  34. Iterator Example // some #includes … int main( ) { const int SIZE = 4; vector<int> inums; for (int i = 0; i < SIZE; i++) inums.push_back(i); vector<int>::iterator p; p = inums.begin( ); 1st – create a vector 2nd – fill it with values 3rd – create an iterator 4th – set the iterator to the beginning of the vector

  35. Iterator Example // some #includes … int main( ) { const int SIZE = 4; vector<int> inums; for (int i = 0; i < SIZE; i++) inums.push_back(i); vector<int>::iterator p; p = inums.begin( ); cout << p[ 1 ] << endl; 1st – create a vector 2nd – fill it with values 3rd – create an iterator 4th – set the iterator to the beginning of the vector 5th – use the iterator to access element 1

  36. Iterator Example // some #includes … int main( ) { const int SIZE = 4; vector<int> inums; for (int i = 0; i < SIZE; i++) inums.push_back(i); vector<int>::iterator p; p = inums.begin( ); cout << p[ 1 ] << endl; cout << *(p + 1) << endl; 1st – create a vector 2nd – fill it with values 3rd – create an iterator 4th – set the iterator to the beginning of the vector 5th – use the iterator to access element 1 alternate syntax

  37. Using an Iterator to Move Through a Container for (p = inums.begin( ); p != inums.end( ); p++) cout << *p;

  38. Constant and Mutable Iterators A constant iterator allows you to dereference the iterator to read the value pointed to. You cannot change the value. A mutable iterator allows you to dereference the iterator to read the value pointed to, or store a new value at that element.

  39. Some container classes only support constant iterators. If a container supports both constant and mutable iterators, and you want a constant iterator, you must declare it as using std::vector<int>::const_iterator; . . . const_iterator p = container.begin( );

  40. Iterator Adapters The Standard Template Library provides three variations on the normal iterator. These are Reverse Iterators Insert Iterators Stream Iterators

  41. Reverse Iterators Given an iterator, p, you might be tempted to try for (p = container.end( ); p != container.begin( ); p--) . . . to iterate backwards through a container. However, in general this will not work, because the begin( ) function returns a real iterator while the end( ) function returns a sentinel. The specific use of the sentinel is to test whether or not you have reached the last element. It does not work like a real iterator.

  42. To navigate backwards through a container, use a reverse iterator, as in the following example. reverse_iterator rp; for (rp = c.rbegin( ); rp != c.rend( ); rp++) { . . . ++ moves to the previous element! this function returns a sentinel to use when testing for the start of the container this function returns an iterator pointing to the last element in the container c

  43. Insert Iterator The insert iterator adapter turns a normal assignment operation into an insert operation.

  44. Back Inserter Front Inserter General Inserter These make an assignment operation work as an insertion. Inserters must be initialized with their containers when they are created. Back_insert_iterator<vector<int> > iter(collection);

  45. Or you can use the function back_inserter( ) which creates the back_inserter and inserts an element at the same time. back_inserter(collection) = 45;

  46. int main( ) { list<int> collection; collection.push_front(5); collection.push_front(7); front_inserter(collection) = 44; front_inserter(collection) = 60; list<int>::iterator p; for (p = collection.begin( ); p != collection.end( ); p++) { cout << *p << endl; } cin.get(); return 0; } Inserts the value at the front of the container, using the push_front function…

  47. So … what’s the big deal? Consider the following code that copies one vector to another:

  48. #include <vector> using std::vector; #include <algorithm> using std::copy; const int SIZE = 5;

  49. int main( ) { // declare two arrays to load the vectors // arr1 contains odd digits // arr2 contains even digits int arr1[] = {1, 3, 5, 7, 9}; int arr2[] = {0, 2, 4, 6, 8}; // Now declare the vectors vector<int> odds; vector<int> evens; // The loop loads the vectors from the arrays for (int i = 0; i < SIZE; i++) { odds.push_back (arr1[i]); evens.push_back (arr2[i]); }

  50. 1 3 5 7 9 odds 0 2 4 6 8 evens

More Related