Lambda Expression in C++ 11

C++ 11 introduces lambda allow you to write the inline, anonymous functor which are cleaner to read and potentially simpler to maintain.

Why Lambdas Used                           

In below example, we have separately written the functor and used in for_each api.

class funct
{
public:
	void operator ()(int &a)
	{
		cout <<a+5;
	}
};

void lambdaExample()
{
	vector<int> v;

	for (int i = 0; i < 5; i++)
	{
		v.push_back(i);
	}

	funct f;
	for_each(v.begin(), v.end(), f);
}

By using lambda, above example become in simplest form:

void lambdaExample()
{
	vector<int> v;

	for (int i = 0; i < 5; i++)
	{
		v.push_back(i);
	}

	for_each(v.begin(), v.end(), [] (const int & a) { cout<< a+5;});
}

Return Values

By default, if your lambda does not have a return statement, it defaults to void. If you have a simple return expression, the compiler will deduce the type of the return value:

[] () { return 1;}       // compilers knows this return type is integer

However when you start to write the complex lambdas then you will quickly encounter cases where the return type can’t be deduced by the compiler, e.g.

void fun( int val)
{
        [](const double & a) {
	      if (a < 0.0001)
		 return 1;
              else
		return a;
        }
}

To resolve this you have to explicitly specify a return type for a lambda function, using ->

void fun( int val)
{
    [](const double & a) -> double {
	if (a < 0.0001)
		return 1;
	else
		return a;
    }
}

Capturing variables

So far we have not used anything other than what was passed to the lambda within it, but we can also use the other variables, within the lambda.

If you want to access the other variables then you can use the capture clause [], 

You can capture variables outside of the lambda expression either by value (copying) or by reference and make them available inside of the lambda body.

void lambdaExample()
{
	vector<int> v;

	for (int i = 0; i < 5; i++)
	{
		v.push_back(i);
	}
	int val = 5;
	for_each(v.begin(), v.end(), [val](const int & a) { cout << a + val; });
}
  • [&val] capture by reference
  • [&] captures all variables used in the lambda by reference
  • [=] captures all variables used in the lambda by value
  • [&, val] captures variables like with [&], but val by value
  • [=, & val] captures variables like with [=], but val by reference

The generated operator() is const by default, with the implication that captures will be const when you access them by default. This has the effect that each call with the same input would produce the same result, however you can mark the lambda as mutable to request that the operator() that is produced is not const.

e.g. [] () mutable ->T {}  //T is the return type

Lambda functions are available in GCC 4.5 and later, as well as MSVC 10 and version 11 of the Intel compiler.

  • 23
    Shares