Sunday, 15 July 2018

C++ Lambda functions

C++11 provides the ability to create anonymous functions, called lambda functions. It allows a function to be defined at the point where it's needed in another expression. It is a function that we can write inline in our code in order to pass in to another function.


/* lambda.cpp */
#include 
#include 
#include 
using namespace std;

// assign a value to each element of a vector
void assign(int& v)
{
  static int n = 1; v = n++;
}

// print out each element
void print(int v)
{
  cout << v << " ";
}

int main()
{
  vector vec(10);
  // output initial value of each element
  for_each(vec.begin(), vec.end(), print);
  cout << endl;

  // assign a value to each element of a vector
  for_each(vec.begin(), vec.end(), assign);

  // output updated value of each element
  for_each(vec.begin(), vec.end(), print);
  return 0;
}
Output:
$ g++ -std=c++11 -o lambda lambda.cpp
$ ./lambda
0 0 0 0 0 0 0 0 0 0 
1 2 3 4 5 6 7 8 9 10 
Now, we can use lambda functions [](){} for the print() and assign() functions:


int main()
{
  vector vec(10);
  // output initial value of each element
  // for_each(vec.begin(), vec.end(), print); ==>
  for_each(vec.begin(), vec.end(), [](int v) {cout << v << " ";});
  cout << endl;

  // assign a value to each element of a vector
  // for_each(vec.begin(), vec.end(), assign); ==>
  for_each(vec.begin(), vec.end(), [](int& v) {static int n = 1; v = n++;});

  // output updated value of each element
  // for_each(vec.begin(), vec.end(), print); ==>
  for_each(vec.begin(), vec.end(), [](int v) {cout << v << " ";});
  return 0;
}
Here are more sample codes:
int main()
{
    // (1)
    std::cout << [](int a, int b){return a*b; }(4, 5) << std::endl; // 20

    // (2)
    auto f = [](int a, int b) { return a*b; };
    std::cout << f(4, 5) << std::endl;  // 20
}
The (1) and (2) are equivalent, and produced the results, 20.
Return from a lambda function
The compiler can deduce the return value type from a lambda function as shown in the case #1 of the example below. However, still we can explicitly specify its return type as in the case #2:
/* lam.cpp */
#include 
using namespace std;

int main()
{
  /* case #1 - compiler deduces return type */
  cout << [](int n) {return n*n;} (5);
  cout << endl;
  /* case #2 - explicit return type */
  cout << [](int n)->int {return n*n;} (5);

  return 0;
}
Output:
$ g++ -std=c++11 -o lam lam.cpp
$ ./lam
25
25


















No comments:

Post a Comment