Difference between revisions of "Intermediate C++ Game Programming Tutorial 16"
m (Text replacement - "http://www.planetchili.net/" to "https://www.planetchili.net/") |
|||
(6 intermediate revisions by 2 users not shown) | |||
Line 9: | Line 9: | ||
== <span style="color:red">Errata</span> == | == <span style="color:red">Errata</span> == | ||
In the video Chili states that std::remove does not preserve the relative order of elements in the container, but this is fake news! Relative order is preserved: [https://en.cppreference.com/w/cpp/algorithm/remove] | In the video Chili states that std::remove does not preserve the relative order of elements in the container, but this is fake news! Relative order is preserved: [https://en.cppreference.com/w/cpp/algorithm/remove] | ||
+ | |||
+ | In the homework solution there is a part where Chili uses an iterator into a <code>stringstream</code> [https://youtu.be/_1-iES-Eytc?t=626]. This code no longer works due to changes (improvements) to the Visual Studio compiler. Basically, you cannot pass a temporary stream into the iterator constructor. See this: [https://stackoverflow.com/questions/23714445/passing-temporary-istringstream-object-to-istream-iteratorstring] | ||
== Video Timestamp Index == | == Video Timestamp Index == | ||
[https://youtu.be/3J1Pz30IE4Q Tutorial 16] | [https://youtu.be/3J1Pz30IE4Q Tutorial 16] | ||
+ | <div class="mw-collapsible mw-collapsed"><br /> | ||
* Generic Algorithms: how Templates and Iterators make Algorithms independent of Data Types and Containers [https://youtu.be/3J1Pz30IE4Q?t=17s 0:17] | * Generic Algorithms: how Templates and Iterators make Algorithms independent of Data Types and Containers [https://youtu.be/3J1Pz30IE4Q?t=17s 0:17] | ||
* The <code>std::sort</code> algorithm and its requirements [https://youtu.be/3J1Pz30IE4Q?t=43s 0:43] | * The <code>std::sort</code> algorithm and its requirements [https://youtu.be/3J1Pz30IE4Q?t=43s 0:43] | ||
Line 18: | Line 21: | ||
* Modyfing sorting order by passing a comparison function object (functor) as a predicate, like so:<br /><code>std::sort(vec.begin(),vec.end(),std::greater<int>{});</code> [https://youtu.be/3J1Pz30IE4Q?t=3m17s 3:17]<br />Note: vec is a std::vector of integers | * Modyfing sorting order by passing a comparison function object (functor) as a predicate, like so:<br /><code>std::sort(vec.begin(),vec.end(),std::greater<int>{});</code> [https://youtu.be/3J1Pz30IE4Q?t=3m17s 3:17]<br />Note: vec is a std::vector of integers | ||
* Sort custom types, example code for sorting a custom class object by creating a functor, called like so: <br /><code>std::sort(vecObj.begin(),vecObj.end(),Obj::YLess{});</code> [https://youtu.be/3J1Pz30IE4Q?t=4m07s 4:07] | * Sort custom types, example code for sorting a custom class object by creating a functor, called like so: <br /><code>std::sort(vecObj.begin(),vecObj.end(),Obj::YLess{});</code> [https://youtu.be/3J1Pz30IE4Q?t=4m07s 4:07] | ||
− | * Removing items from a container, <code>std::remove</code> and <code>std::remove_if</code> [https://youtu.be/3J1Pz30IE4Q?t=6m11s 6:11] < | + | * Removing items from a container, <code>std::remove</code> and <code>std::remove_if</code> [https://youtu.be/3J1Pz30IE4Q?t=6m11s 6:11] |
+ | <div class="mw-collapsible-content"> | ||
+ | ** Create a functor as a unary predicate for the <code>std::remove</code> function to remove elements using a threshold variable [https://youtu.be/3J1Pz30IE4Q?t=8m28s 8:28] | ||
+ | ** Use container member function <code>erase()</code> to correct the endpoint of the container after the remove operation [https://youtu.be/3J1Pz30IE4Q?t=9m51s 9:51] | ||
+ | </div> | ||
* Introducing Lambda functions to replace custom functors [https://youtu.be/3J1Pz30IE4Q?t=11m51s 11:51] | * Introducing Lambda functions to replace custom functors [https://youtu.be/3J1Pz30IE4Q?t=11m51s 11:51] | ||
− | * Using the Lambda capture to bring in variables into the Lambda function [https://youtu.be/3J1Pz30IE4Q?t=13m34s 13:34]< | + | * Using the Lambda capture to bring in variables into the Lambda function [https://youtu.be/3J1Pz30IE4Q?t=13m34s 13:34] |
+ | <div class="mw-collapsible-content"> | ||
+ | ** Capture syntax explained: <code>[var]</code>,<code>[&var]</code>,<code>[=]</code>,<code>[&]</code>,<code>[newvar=var+10]</code>,<code>[this]</code>, capture multiple variables, mix&match capture modes | ||
+ | ** Stateful Lambdas; changing captured lambda variables using the <code>mutable</code> flag [https://youtu.be/3J1Pz30IE4Q?t=15m59s 15:59] | ||
+ | </div> | ||
* Some anxiety-reducing consolation by Chili [https://youtu.be/3J1Pz30IE4Q?t=16m40s 16:40] | * Some anxiety-reducing consolation by Chili [https://youtu.be/3J1Pz30IE4Q?t=16m40s 16:40] | ||
− | * Syntax for a callable Lambda function [https://youtu.be/3J1Pz30IE4Q?t=17m03s 17:03] < | + | * Syntax for a callable Lambda function [https://youtu.be/3J1Pz30IE4Q?t=17m03s 17:03] |
+ | <div class="mw-collapsible-content"> | ||
+ | ** Make it callable once: <code>[...](...){...}(vec.front());</code>, functor is destroyed immediately | ||
+ | ** Keep the functor using <code>auto mylamb = [...](...){...};</code>, which can be called by <code>bool result = mylamb(vec.front());</code>, or <code>std::remove_if(...,...,mylamb);</code> | ||
+ | </div> | ||
* The power of C++ is in its flexibility. Example code for converting a string to lowercase:<br /><code>std::transform(str.begin(),str.end(),str.begin(),::tolower);</code>[https://youtu.be/3J1Pz30IE4Q?t=17m49s 17:49] | * The power of C++ is in its flexibility. Example code for converting a string to lowercase:<br /><code>std::transform(str.begin(),str.end(),str.begin(),::tolower);</code>[https://youtu.be/3J1Pz30IE4Q?t=17m49s 17:49] | ||
* Homework assignment [https://youtu.be/3J1Pz30IE4Q?t=18m39s 18:39] | * Homework assignment [https://youtu.be/3J1Pz30IE4Q?t=18m39s 18:39] | ||
− | * Introducing the [ | + | * Introducing the Algorithm [[STD Gems]] series that takes a deep dive into its functionality [https://youtu.be/3J1Pz30IE4Q?t=19m20s 19:20] |
+ | </div> | ||
== Homework == | == Homework == | ||
Solve the problems in Source.cpp attached below using the <algorithm> library and other parts of the standard library as extensively as possible. As a bonus problem, implement the sprite drawing effect shown at the end of the video using a lambda function. | Solve the problems in Source.cpp attached below using the <algorithm> library and other parts of the standard library as extensively as possible. As a bonus problem, implement the sprite drawing effect shown at the end of the video using a lambda function. | ||
− | * [ | + | * [https://www.planetchili.net/downloads/I16-HW.zip Source.cpp (homework file)] |
* [https://github.com/planetchili/sprite Sprite Repo (for bonus problem)] | * [https://github.com/planetchili/sprite Sprite Repo (for bonus problem)] | ||
+ | |||
+ | The homework solution video can be found [https://youtu.be/_1-iES-Eytc here] | ||
== Related Series == | == Related Series == |
Latest revision as of 13:26, 5 May 2022
In the video we take a look at a couple of bangers from <algorithm>
, and we learn what lambda functions are and how to use them.
Contents
Topics Covered
- Algorithms
std::sort
andstd::remove_if
- Concepts (as in, type concepts like Comparable)
-
<functional>
functors as predicates - Lambda functions
Errata
In the video Chili states that std::remove does not preserve the relative order of elements in the container, but this is fake news! Relative order is preserved: [1]
In the homework solution there is a part where Chili uses an iterator into a stringstream
[2]. This code no longer works due to changes (improvements) to the Visual Studio compiler. Basically, you cannot pass a temporary stream into the iterator constructor. See this: [3]
Video Timestamp Index
- Generic Algorithms: how Templates and Iterators make Algorithms independent of Data Types and Containers 0:17
- The
std::sort
algorithm and its requirements 0:43 - Sorting a (forward) list
std::list
, using its member functionstd::list::sort()
2:16 - Introducing Concepts / named requirements of types (e.g., the
Compare
requirement ofstd::sort
) 2:54 - Modyfing sorting order by passing a comparison function object (functor) as a predicate, like so:
std::sort(vec.begin(),vec.end(),std::greater<int>{});
3:17
Note: vec is a std::vector of integers - Sort custom types, example code for sorting a custom class object by creating a functor, called like so:
std::sort(vecObj.begin(),vecObj.end(),Obj::YLess{});
4:07 - Removing items from a container,
std::remove
andstd::remove_if
6:11
- Introducing Lambda functions to replace custom functors 11:51
- Using the Lambda capture to bring in variables into the Lambda function 13:34
- Capture syntax explained:
[var]
,[&var]
,[=]
,[&]
,[newvar=var+10]
,[this]
, capture multiple variables, mix&match capture modes - Stateful Lambdas; changing captured lambda variables using the
mutable
flag 15:59
- Capture syntax explained:
- Make it callable once:
[...](...){...}(vec.front());
, functor is destroyed immediately - Keep the functor using
auto mylamb = [...](...){...};
, which can be called bybool result = mylamb(vec.front());
, orstd::remove_if(...,...,mylamb);
- Make it callable once:
Homework
Solve the problems in Source.cpp attached below using the <algorithm> library and other parts of the standard library as extensively as possible. As a bonus problem, implement the sprite drawing effect shown at the end of the video using a lambda function.
The homework solution video can be found here
Related Series
For an in-depth look into the <algorithm> library and beyond, check out STD Gems.