Illustrates lambdas and the several ways they capture local state.
/////////////////////////////////////////////////////////////////////
// Lambdas.cpp - demonstrate lambda capture //
// //
// Jim Fawcett, CSE687 - Object Oriented Design, Spring 2015 //
/////////////////////////////////////////////////////////////////////
/*
* When compiled a lambda definition is translated into a functor
* with operator() defining the code of the lambda. Any referenced
* data from the local scope becomes member data of the functor and
* gets passed around with the lambda.
*
* Lambdas are defined like this:
* 1. [=] (arguments)
* { code to execute may include names of local data as well as arguments };
* The [=] means that local data, like i below, are captured by value.
* 2. [&] (arguments)
* { code to execute may include names of local data as well as arguments };
* The [&] means that local data is captured by reference so must be in
* scope when the lambda executes.
* 3. [localVar1, &localVar2] (arguments)
* { code to execute includes localVar1 by value and localVar2 by reference }
*/
#include <functional>
#include <iostream>
#include <sstream>
//----< create a lambda and bind to a std::function >----------------
/*
* Lambda copies captured values, e.g., [=]
*/
std::function<std::string()> CreateLambda1(int i)
{
// this std function converts an integer to a string
std::function<std::string()> f = [=]()
{
std::ostringstream convert;
convert << i; // lambda captures value of i
return convert.str();
};
return f;
}
//----< create a lambda and bind to a std::function >----------------
/*
* Lambda copies captured values, e.g., []
*/
std::function<std::string(int)> CreateLambda2()
{
// this std function converts an integer to a string
std::function<std::string(int)> f = [](int i)
{
std::ostringstream convert;
convert << i; // lambda captures value of i
return convert.str();
};
return f;
}
//----< create a lambda and bind to a std::function >----------------
/*
* Lambda captures a reference to i and the value of j, e.g., [&i, j]
*/
std::function<std::string()> CreateLambda3(int& i)
{
// this std function converts integers to a string
int j = 40;
std::function<std::string()> f = [&i, j]()
{
std::ostringstream convert;
convert << i + j; // lambda captures reference to
return convert.str(); // external i - would be an error
}; // if i was passed by value to
return f; // CreateLambda3(int i)
}
//----< create a lambda and bind to a std::function >----------------
/*
* Lambda captures a reference to i that will become invalid when
* returning from invocation and a copy of j which will be valid,
* e.g., [&i, j]
*/
std::function<std::string()> CreateLambda4()
{
// this std function converts integers to a string
int i = 2;
int j = 40;
std::function<std::string()> f = [&i, j]()
{
std::ostringstream convert;
convert << i + j; // error here - will return invalid reference
return convert.str(); // to temporary value of i along with valid
}; // copy of j, e.g., [&i, j]
return f;
}