Download presentation
Presentation is loading. Please wait.
Published byGordon Cobb Modified over 5 years ago
1
STL Iterators Separating Container from Data Access
2
Last Tutorial C++ Templates The Standard Template Library (STL)
Function templates (swap, minimum, QuickSort) Class templates (pair) The Standard Template Library (STL) Containers Library – specifically std::vector
3
Today’s Questions What is an iterator?
What operations can I perform on an iterator? What is an std::list? How is an std::list different from an std::vector?
4
What is an iterator? An iterator identifies an element in a container
Similar to a pointer An iterator allows us to access an element in a container Also similar to a pointer An iterator allows us to move between elements in a container Similar to pointer arithmetic An iterator is restricted to efficient operations
5
Iterator versus operator[]
Why not just use array[index] to access elements? operator[] implies random access Random access is not supported by all data structures In the STL, all containers have iterators defined Each of these iterator types are different: std::vector<int>::iterator std::vector<float>::iterator std::list<int>::iterator
6
std::vector functions
Already Covered Today’s New Functions Accessing – operator[] Inserting – push_back() Modifying – operator[] Querying – size() Complexity of all of the above: O(1) Iterating – begin() Returns an iterator to the first element Iterating – end() Returns an iterator to the element following the last element Used for bounds checking
7
Where is begin and end? … 1 2 3 4 5 n - 1 my_vector.size() = n
1 2 3 4 5 n - 1 my_vector.begin() my_vector.end() Note: one past the end!
8
Operating on iterators
std::vector<int> numbers = {1, 2, 3, 4}; // Case 1 std::vector<int>::iterator it = numbers.begin(); it = 5; // Case 2 it++; // Case 3 it--; // Case 4 int x = *it; // Case 5 it != numbers.end(); // Case 6 it < numbers.end(); // Case 7 *it = 27; // Case 8 it = numbers.begin() + 2; // Case 9 Case Allowed? Explanation 1 Yes Points to the start of vector (1) 2 No 5 is an int, not an iterator 3 Points to the next element (2) 4 Points to the prior element (1) 5 Sets x to the element value 6 Checks if points to valid element 7 Checks if comes before the end 8 Modifies the element at it 9 Points to the third element Should add animated diagram to illustrate iterator_operations.cpp
9
Looping Through a Vector
std::vector<int> numbers = {1, 2, 3, 4}; // using indices for(size_t i = 0; i < numbers.size(); ++i) { std::cout << numbers[i] << " "; } std::cout << "\n"; // using iterators for(std::vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) { std::cout << *it << " "; Declare iterator type Initialize to first element Ensure iterator valid Advance to next element Dereference to get value of the element vector_looping.cpp
10
Extract the Negative Values of the Vector
std::vector<int> extract_negatives(std::vector<int> & integers) { std::vector<int> negatives; for(std::vector<int>::iterator it = integers.begin(); it != integers.end(); ++it) { if(*it < 0) { negatives.push_back(*it); } return negatives; Using iterators, loop over the integers vector and add elements that are negative to the negatives vector. extract_negatives.cpp
11
Erase the Negative Values of the Vector
void remove_negatives(std::vector<int> & integers) { for(std::vector<int>::iterator it = integers.begin(); it != integers.end();) { if(*it < 0) { it = integers.erase(it); } else { it++; } Do not increment it in the for loop statement erase(iterator) will return an iterator to the next element it is incremented if nothing is erased remove_negatives.cpp
12
What does erase do? *it processed elements unprocessed elements
negative elements copied it2 = integers.erase(it); processed elements unprocessed elements *it2
13
How does erase perform? erase(iterator)
Accepts an iterator to the element that should be erased Returns the next iterator in the vector Complexity: O(n) What is the complexity of remove_negatives? Consider a vector that contains all negative values
14
How does erase perform? erase(iterator)
Accepts an iterator to the element that should be erased Returns the next iterator in the vector Complexity: O(n) What is the complexity of remove_negatives? Consider a vector that contains all negative values We loop over n elements Worst case: we erase n times Complexity: O(n2)
15
std::list is a Doubly Linked List
next data previous next data previous next data previous next data previous … head tail Double links (next and previous) allow for bi-directional access Fast insert and erase Only need to update neighbours
16
std::vector versus std::list
begin O(1) end push_back size O(1) (since C++11) operator[] Not available erase(iterator) O(n) Iterator Type Random Access it++ is allowed it-- is allowed it + 5 is allowed Bidirectional it + 5 is not allowed
17
Iterator Categories Category Available Operations Random Access
(e.g. vector) Bidirectional (e.g. list) Forward (e.g. forward_list) Read Increment Decrement *it it++ it-- it + 5 *it it++ it-- *it it++
18
Replacing std::vector with std::list
void remove_negatives(std::list<int>& integers) { for(std::list<int>::iterator it = integers.begin(); it != integers.end();) { if(*it < 0) { it = integers.erase(it); } else { it++; } void remove_negatives(std::vector<int>& integers) { for(std::vector<int>::iterator it = integers.begin(); it != integers.end();) { if(*it < 0) { it = integers.erase(it); } else { it++; } vector_vs_list.cpp
19
Replacing std::vector with std::list
Because of iterators, we can quickly switch from vector to list This is one reason why iterators are so useful With std::list, remove_negatives is O(n) Be careful: not all code works interchangeably with all containers Change to explicit example vector_vs_list.cpp
20
Using C++11’s auto keyword
Instead of specifying a type (such as int), we can use the auto keyword auto asks the compiler to determine the type for us Using auto can help… Save on typing Keep code compiling when you switch types around frequently Caution: You should always know what the actual type will be The type is still static auto does not mean the type can change dynamically – this is not python
21
Simplifying Iterator Code with auto
// Before C++11 for(std::vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) { std::cout << *it << " "; } std::cout << "\n"; // With C++11 for(auto it = numbers.begin(); it != numbers.end(); ++it) { auto_iterators.cpp
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.