Last active
August 24, 2020 04:19
-
-
Save cmgg/fbfbb63f057855ec3e958755f163d528 to your computer and use it in GitHub Desktop.
Reference for lambda expressions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <algorithm> | |
#include <string> | |
#include <iostream> | |
#include <memory> | |
#include "Resource.h" | |
void simple_example() | |
{ | |
auto isOdd = [](int candidate) { return candidate % 2 != 0; }; | |
std::vector<int> nums { 2,3,4,-1,1 }; | |
int odds = std::count_if(std::begin(nums), std::end(nums), isOdd); | |
} | |
/* | |
* [] captures nothing, use only function parameters | |
* [x,y] capture x and y by value | |
* - Copies are made | |
* - Lambda can be used when x and y have gone out of scope | |
* [&x,&y] capture x and y by reference | |
* - No copies, changes affect the original | |
* - Dangling references may be an issue | |
* [x=a+1,y=std::move(b)] alias or move capture | |
* - Lets you initialize the lambda member variables before using them | |
* - Useful in specific cases | |
* [=] copy "everything" by value | |
* - The compiler generates code for you | |
* - It looks at the body of the lambda and see what variables from the calling scope being used | |
* [&] copy "everything" by reference, same as above | |
* | |
* Declaring the lambda as "mutable" allows you to change values captured by reference | |
*/ | |
void capture_example() | |
{ | |
std::cout << "capture_example()\n"; | |
std::vector<int> nums { 2,3,4,-1,1 }; | |
int x = 3, y = 7; | |
std::string message = "\telements between "; | |
message += std::to_string(x) + " and " + std::to_string(y) + " inclusive: "; | |
// Capturing explicitly by value and by reference [x, y, &message] | |
std::for_each(std::begin(nums), std::end(nums), | |
[x, y, &message](int n) | |
{ | |
if (n >= x && n <= y) | |
message += " " + std::to_string(n); | |
} | |
); | |
std::cout << message << '\n'; | |
x = y = 0; | |
// Capture x by value, the rest by reference | |
std::for_each(std::begin(nums), std::end(nums), | |
[&, x](int element) mutable | |
{ | |
x += element; | |
y += element; | |
} | |
); | |
// Braces for scope | |
{ | |
auto pResource = std::make_unique<Resource>(", "); | |
std::for_each(std::begin(nums), std::end(nums), | |
// Move semantics are used instead of a reference to the unique pointer because | |
// if this is run as a multithreaded program, the thread handling the lambda | |
// could wake up after this scope is gone, making pResource a dangling pointer. | |
[=, &message, p=std::move(pResource)](int n) | |
{ | |
if (n >= x && n <= y) | |
message += p->GetName() + std::to_string(n); | |
} | |
); | |
// Move semantics gave the ownership of pResource to the lambda function | |
// so at this point, pResource is empty | |
} | |
// pResource goes out of scope and its destroyed | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
// simple_example(); | |
capture_example(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment