Difference between revisions of "Intermediate C++ Game Programming Tutorial 15"
(Created page with "In this tutorial we learn how to make our own goddamn templates. So much power. Drunk with it we are. We also learn about the concept of a "functor" (dumb name, clever idea),...") |
(→Video Timestamp Index) |
||
(82 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | In this | + | Iterators are just fancy pointers for containers. In this video we learn how to use iterators, what they're good for, and why we go through all this goddamn trouble in the first place (answer: because they make my dick hard). |
== Topics Covered == | == Topics Covered == | ||
− | * | + | * Iterator operations (increment/decrement, dereference, add/sub, etc.) |
− | * | + | * Getting iterators from containers (begin/end) |
− | * | + | * Sequence ranges [closed,open) |
− | * | + | * Container manipulation functions (erase/insert) |
− | * | + | * Iterators and template algorithms (generic algorithms) |
+ | * Iterator categories (random access/bidirectional/forward etc.) | ||
+ | * const_iterator (cbegin/cend) & reverse iterators (rbegin/rend) | ||
+ | * Free iterator functions (std::begin/end/advance/next/prev) | ||
+ | * Iterator adapters (back_inserter, ostream_iterator) | ||
== Video Timestamp Index == | == Video Timestamp Index == | ||
− | [https://youtu.be/ | + | [https://youtu.be/h5aFJJp1Stw Tutorial 15] |
+ | * Why should I care about iterators? [https://youtu.be/h5aFJJp1Stw?t=21s 0:21] | ||
+ | * What are iterators? [https://youtu.be/h5aFJJp1Stw?t=49s 0:49] | ||
+ | * Valid range for an iterator [first,last) [https://youtu.be/h5aFJJp1Stw?t=1m27s 1:27] | ||
+ | * What is the type of an iterator / iterator member type definitions [https://youtu.be/h5aFJJp1Stw?t=1m55s 1:55] | ||
+ | * Getting an iterator from a container, using the example <code>std::vector<int>::iterator i = v.begin();</code> [https://youtu.be/h5aFJJp1Stw?t=2m34s 2:34] | ||
+ | * Simple <code>for</code> loops with iterators & iterator arithmetic [https://youtu.be/h5aFJJp1Stw?t=3m52s 3:52] | ||
+ | * Code safety through Iterator protection when misused / out of bounds / invalidated [https://youtu.be/h5aFJJp1Stw?t=6m48s 6:48] | ||
+ | * Container manipulation function <code>erase</code> [https://youtu.be/h5aFJJp1Stw?t=7m20s 7:20] | ||
+ | * Iterators that return iterators (recovering from an invalidation), e.g. <code>i = v.erase(i);</code> [https://youtu.be/h5aFJJp1Stw?t=10m17s 10:17] | ||
+ | * Container manipulation function <code>insert</code> / <code>emplace</code> [https://youtu.be/h5aFJJp1Stw?t=11m45s 11:45] | ||
+ | * Why not just use indices? Iterators and template algorithms (generic algorithms) [https://youtu.be/h5aFJJp1Stw?t=12m36s 12:36] | ||
+ | * Introducing the <code>forward_list</code> container [https://youtu.be/h5aFJJp1Stw?t=13m40s 13:40] | ||
+ | * Template a function on an Iterator: writing a generic function that can be applied to any type of container, e.g.<br /><code>template<typename Iter></code><br /><code>void print(Iter begin, Iter end){...}</code> [https://youtu.be/h5aFJJp1Stw?t=14m35s 14:35] | ||
+ | * Introducing the Algorithms library [https://youtu.be/h5aFJJp1Stw?t=15m16s 15:16] | ||
+ | * The five types of iterators: input, output, forward, bidirectional, random access [https://youtu.be/h5aFJJp1Stw?t=15m29s 15:29] | ||
+ | * Constant inerators [https://youtu.be/h5aFJJp1Stw?t=16m26s 16:26] | ||
+ | * Reverse iterators [https://youtu.be/h5aFJJp1Stw?t=17m39s 17:39] | ||
+ | * Free functions and iterators in the Standard library (STL) <code>std::begin(container_object)</code>, works on C-arrays so generic Algorithms can be applied [https://youtu.be/h5aFJJp1Stw?t=18m22s 18:22] | ||
+ | * Special purpose iterators: Iterator adapters (<code>back_inserter</code>, <code>ostream_iterator</code>) [https://youtu.be/h5aFJJp1Stw?t=20m32s 20:32] | ||
+ | * Example code for handling operations on different types of containers, i.e.<br /><code>template<typename Iter1, typename Iter2, typename Iter3></code><br /><code>void sum(Iter1 in1, Iter1 end1, Iter2 in2, Iter3 out){...}</code> [https://youtu.be/h5aFJJp1Stw?t=20m41s 20:41] | ||
+ | * Example applying a <code>back_insert_iterator</code> on a <code>std::list<float> lf</code>, calling the <code>sum</code> function like so:<br /><code>sum( vi.begin(), vi.end(), vf.begin(), std::back_inserter(lf) )</code> [https://youtu.be/h5aFJJp1Stw?t=22m22s 22:22] | ||
+ | * Example code using Stream iterators, e.g. an <code>ostream_iterator</code>, like so:<br /><code>sum( vi.begin(), vi.end(), vf.begin(), std::ostream_iterator<float>(std::cout,", ")</code> [https://youtu.be/h5aFJJp1Stw?t=23m36s 23:36] | ||
+ | * Homework assignment [https://youtu.be/h5aFJJp1Stw?t=24m33s 24:33] | ||
− | == | + | == Answer to erase puzzle == |
− | + | The reason why we do not increment the iterator <code>i</code> in the for loop, but instead increment it conditionally in the body of the loop is, if we erase an element, the returned iterator will point to the next element after the erased one, and if we were incrementing every iteration of the loop, it would skip all elements that immediately follow an erased element. Instead, we only increment if we did not erase an element, and this ensures that all elements are tested. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
== Homework == | == Homework == | ||
− | Modify stack to work with range based for loops. | + | Modify our linked list stack to work with range based for loops. You are not allowed to modify any code outsize of the <code>Stack</code> class. If you want an extra challenge after completing Level 1, you can uncomment the code for Level 2 and try to get it to compile as well. |
+ | |||
+ | [https://github.com/planetchili/LinkedListStack Linked List Stack Repo] | ||
+ | |||
+ | [https://youtu.be/FxawtltnvIc Solution video] | ||
== Links == | == Links == | ||
− | [http://www.cplusplus.com/reference/iterator/ Iterator | + | [http://www.cplusplus.com/reference/iterator/ Iterator Category Reference]<br /> |
− | + | [https://gist.github.com/jeetsukumaran/307264 Custom Iterator Example] | |
− | + | ||
− | + | ||
== See also == | == See also == | ||
− | * [[Intermediate C++ Game Programming Tutorial | + | * [[Intermediate C++ Game Programming Tutorial 16|Next in series (Tutorial 16)]] |
* [[Intermediate C++ Game Programming Series]] | * [[Intermediate C++ Game Programming Series]] |
Latest revision as of 03:05, 24 September 2019
Iterators are just fancy pointers for containers. In this video we learn how to use iterators, what they're good for, and why we go through all this goddamn trouble in the first place (answer: because they make my dick hard).
Contents
Topics Covered
- Iterator operations (increment/decrement, dereference, add/sub, etc.)
- Getting iterators from containers (begin/end)
- Sequence ranges [closed,open)
- Container manipulation functions (erase/insert)
- Iterators and template algorithms (generic algorithms)
- Iterator categories (random access/bidirectional/forward etc.)
- const_iterator (cbegin/cend) & reverse iterators (rbegin/rend)
- Free iterator functions (std::begin/end/advance/next/prev)
- Iterator adapters (back_inserter, ostream_iterator)
Video Timestamp Index
- Why should I care about iterators? 0:21
- What are iterators? 0:49
- Valid range for an iterator [first,last) 1:27
- What is the type of an iterator / iterator member type definitions 1:55
- Getting an iterator from a container, using the example
std::vector<int>::iterator i = v.begin();
2:34 - Simple
for
loops with iterators & iterator arithmetic 3:52 - Code safety through Iterator protection when misused / out of bounds / invalidated 6:48
- Container manipulation function
erase
7:20 - Iterators that return iterators (recovering from an invalidation), e.g.
i = v.erase(i);
10:17 - Container manipulation function
insert
/emplace
11:45 - Why not just use indices? Iterators and template algorithms (generic algorithms) 12:36
- Introducing the
forward_list
container 13:40 - Template a function on an Iterator: writing a generic function that can be applied to any type of container, e.g.
template<typename Iter>
void print(Iter begin, Iter end){...}
14:35 - Introducing the Algorithms library 15:16
- The five types of iterators: input, output, forward, bidirectional, random access 15:29
- Constant inerators 16:26
- Reverse iterators 17:39
- Free functions and iterators in the Standard library (STL)
std::begin(container_object)
, works on C-arrays so generic Algorithms can be applied 18:22 - Special purpose iterators: Iterator adapters (
back_inserter
,ostream_iterator
) 20:32 - Example code for handling operations on different types of containers, i.e.
template<typename Iter1, typename Iter2, typename Iter3>
void sum(Iter1 in1, Iter1 end1, Iter2 in2, Iter3 out){...}
20:41 - Example applying a
back_insert_iterator
on astd::list<float> lf
, calling thesum
function like so:sum( vi.begin(), vi.end(), vf.begin(), std::back_inserter(lf) )
22:22 - Example code using Stream iterators, e.g. an
ostream_iterator
, like so:sum( vi.begin(), vi.end(), vf.begin(), std::ostream_iterator<float>(std::cout,", ")
23:36 - Homework assignment 24:33
Answer to erase puzzle
The reason why we do not increment the iterator i
in the for loop, but instead increment it conditionally in the body of the loop is, if we erase an element, the returned iterator will point to the next element after the erased one, and if we were incrementing every iteration of the loop, it would skip all elements that immediately follow an erased element. Instead, we only increment if we did not erase an element, and this ensures that all elements are tested.
Homework
Modify our linked list stack to work with range based for loops. You are not allowed to modify any code outsize of the Stack
class. If you want an extra challenge after completing Level 1, you can uncomment the code for Level 2 and try to get it to compile as well.
Links
Iterator Category Reference
Custom Iterator Example