Skip to content

Latest commit

 

History

History
120 lines (90 loc) · 2.69 KB

lambda.cpp11.adoc

File metadata and controls

120 lines (90 loc) · 2.69 KB

lambda

Notice that in C++ (and C), it is only possible to provide a function declaration inside a function, not to provide an implementation.

Lambdas gives us the possiblity to implement local (even stateful) functions.

Syntax

[ captures ] ( params ) -> ret { body }
[ captures ] ( params )        { body }
[ captures ]                   { body }

A lambda expression defines an unique class type.

The captures is a comma-separated list of zero or more captures and/or & and =; it defines the variables that are accessible from within the lambda.

  • & captures the used variables by reference

  • = captures the used variables by copy

Glue code for algorithms

// without lambda, requires global function
bool less_five(int n){ return n < 5;}

void foo(std::vector<int>& c){
  c.erase(
    std::remove_if(c.begin(), c.end(), less_five),
    c.end()
  );
}

// with lambda
void bar(std::vector<int>& c){
  c.erase(
    std::remove_if(c.begin(), c.end(), [](int n){ return n < 5; }),
    c.end()
  );
}

Glue code for algorithms

// without lambda, requires global class declaration (until c++03)
struct less_than{
  int sup;
  less_than(int sup_) : sup(sup_){};
  bool operator()(int n){return n < sup;}
};
void foo(std::vector<int>& c, int sup){
  c.erase(
    std::remove_if(c.begin(), c.end(), less_than(sup)),
    c.end()
  );
}

// with lambda
void bar(std::vector<int>& c, int sup){
  c.erase(
    std::remove_if(c.begin(), c.end(), [sup](int n){return n < sup;}),
    c.end()
  );
}

Stateful functions (without globals)

int i = 0;
auto counter = [&i](){return ++i;}
counter(); // returns 1
counter(); // returns 2

non trivial initialisation

So that objects can more easily be defined as constants (for example as alternative to the ternary operator), or in a thread-safe way:

class complex_obj{ /*...*/ };

const complex_obj co = [](){
  // ...
}();

const int i = [](){
  // ...
}();

Decay to function pointers

Lambdas can be passed even to C functions(!)

#include <cstdlib>

int main(){
  atexit([](){std::cout << "goodbye\n";});
}

unless they have a non-empty capture-list.

Lambdas are implemented behind the scenes as structures