Wednesday, 20 December 2017

c++ - What is a lambda expression in C++11?

One of the best explanation of lambda
expression
is given from author of C++ Bjarne
Stroustrup
in his book ***The C++ Programming
Language***
chapter 11 ( href="https://rads.stackoverflow.com/amzn/click/com/0321563840"
rel="noreferrer">ISBN-13:
978-0321563842):



What
is a lambda expression?





A lambda expression, sometimes also referred to as a
lambda
function or (strictly speaking incorrectly, but
colloquially) as a
lambda, is a simplified notation for
defining and using an anonymous function object. Instead of
defining a named class with an operator(), later making an object of that class, and
finally
invoking it, we can use a
shorthand.





When
would I use
one?



readability="8">

This is particularly useful when we want to pass
an operation as an
argument to an algorithm. In the context of graphical user
interfaces
(and elsewhere), such operations are often referred to as
callbacks.




What
class of problem do they solve that wasn't possible prior to their
introduction?




Here
i guess every action done with lambda expression can be solved without them, but with
much more code and much bigger complexity. Lambda expression this is the way of
optimization for your code and a way of making it more attractive. As sad by Stroustup
:





effective ways of
optimizing




Some
examples



via lambda
expression




void
print_modulo(const vector& v, ostream& os, int m) // output v[i] to
os if v[i]%m==0
{
for_each(begin(v),end(v),

[&os,m](int x) {
if (x%m==0) os << x << '\n';

});
}



or
via function



class Modulo_print
{
ostream& os; // members to hold the capture list int m;

public:
Modulo_print(ostream& s, int mm) :os(s), m(mm) {}

void operator()(int x) const
{
if (x%m==0) os << x <<
'\n';

}

};


or
even



void print_modulo(const
vector& v, ostream& os, int m)
// output v[i] to os if
v[i]%m==0
{
class Modulo_print {
ostream& os; //
members to hold the capture list

int m;

public:
Modulo_print (ostream& s, int mm) :os(s), m(mm) {}

void operator()(int x) const
{
if (x%m==0) os << x <<
'\n';
}
};

for_each(begin(v),end(v),Modulo_print{os,m});

}



if
u need u can name lambda expression like
below:



void print_modulo(const
vector& v, ostream& os, int m)
// output v[i] to os if
v[i]%m==0
{
auto Modulo_print = [&os,m] (int x) { if (x%m==0)
os << x << '\n'; };

for_each(begin(v),end(v),Modulo_print);

}



Or assume
another simple sample



void
TestFunctions::simpleLambda() {
bool sensitive = true;

std::vector v =
std::vector({1,33,3,4,5,6,7});


sort(v.begin(),v.end(),
[sensitive](int x, int y) {


printf("\n%i\n", x < y);
return sensitive ? x < y : abs(x) <
abs(y);
});


printf("sorted");

for_each(v.begin(), v.end(),
[](int x) {
printf("x - %i;",
x);
}


);
}


will
generate next



readability="5">

0




1




0




1



0




1




0




1




0



1




0 sortedx - 1;x - 3;x - 4;x - 5;x - 6;x - 7;x -
33;





[]
- this is capture list or lambda introducer: if
lambdas require no access to their local environment we can use
it.



Quote from
book:





The first character of a lambda expression is always
[. A lambda
introducer can take various
forms:



[]: an
empty capture list. This
implies that no local names from the surrounding
context can be used

in the lambda body. For such lambda
expressions, data is obtained from
arguments or from nonlocal variables.



[&]:
implicitly capture by
reference. All local names can be used. All local
variables are
accessed by reference.




[=]: implicitly capture by value. All
local
names can be used. All names refer to copies of the local
variables
taken at the point of call of the lambda
expression.





[capture-list]: explicit capture; the capture-list is the
list of names of local variables to be captured (i.e., stored in the object) by
reference or by value. Variables with names preceded by & are captured by

reference. Other variables are captured by value. A capture list can
also
contain this and names followed by ... as elements.




[&, capture-list]: implicitly capture by
reference all local variables with names not men- tioned in the list. The capture list
can contain this. Listed names cannot be preceded by &. Variables named in
the
capture list are captured by value.




[=, capture-list]: implicitly capture by value
all local variables with names not mentioned in the list. The capture list cannot
contain this. The listed names must be preceded by &. Vari- ables named in the
capture list are captured by reference.





Note that a local name preceded by & is always captured by

reference and a local name not pre- ceded by & is always captured by

value. Only capture by reference allows modification of variables in
the
calling
environment.




Additional



Lambda
expression
format




href="https://i.stack.imgur.com/03yye.png" rel="noreferrer"> src="https://i.stack.imgur.com/03yye.png" alt="enter image description
here">



Additional
references:

No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print ...