Skip to content

Instantly share code, notes, and snippets.

@cmgg
Last active August 24, 2020 04:19
Show Gist options
  • Save cmgg/fbfbb63f057855ec3e958755f163d528 to your computer and use it in GitHub Desktop.
Save cmgg/fbfbb63f057855ec3e958755f163d528 to your computer and use it in GitHub Desktop.
Reference for lambda expressions
#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