"Hello Lambdas" C++ 0x, a quick guide to Lambdas in C++

The current draft of the new C++ 0x standard includes lambda functions. I think we can expect this to be very popular. I'll show a "Hello, World" example, and then explain the syntax very briefly. In a future posting I’ll write about lambdas and their use with Intel Threading Building Blocks.

Hello, Lambdas, version 1:

template<typename F> 

void Eval( const F& f ) {
    f();
}
void foo() {
    Eval( []{printf("Hello, Lambdas\n");} );
}

Hello, Lambdas, version 2:

void bar() {
    auto f = []{printf("Hello, Lambdas\n"); };
    f();

	}


Lambdas, my quick reference guide:

Compilers that support lambdas will create a unique anonymous functor type for each lambda expression. Lambda expressions are useful as arguments to template functions or with C++0x auto keyword.

Here are some valid uses of lambda to look at before getting into the formal definition:

[&](float x){sum+=x;}

[&]{return *p++;}

[=](float x) {return a*x+b;}

[](float x, float y)->float {

    if(x<y) return x;
    else return y;

	}

A lambda function starts with ‘[‘ and is specified as:

[capture_mode] (formal_parameters) mutable throw() -> return_type {body}

Which is broken down as follows:

[capture_mode]

[&] means captured variables are by-reference, changes will affect variables from outside the body (the surrounding scope when the lambda was defined) when modified in the body
[=]
means captured variables are by-value, changes to them in the body will not affect the value outside the body (being allowed to change the value inside the body does require the 'mutable' keyword be used)
[]   means no capture of variables from other scope(s), any reference to a variable not passed in as a parameter or otherwise defined in the code body will be flagged as undefined by the compiler (perhaps with a polite reminded that you can’t access variables in a lambda from other scopes without a capture specified).

You can specify variables to differ from the default you specify, by naming them in the capture. Therefore a capture of [&,=total] says to capture variables by reference except to capture variable total by value. You can let the default be no capture by specifing variables all explicitly such as [&foo,&bar].

(formal_parameters) can be omitted if there are no parameters and the return type is implicit. Default arguments, variable length argument lists and unnamed parameters are not allowed – otherwise the parameter list is basically like any other.

mutable: An optional keyword "mutable" is required if you want the body to be allowed to modify captured variables that were captured 'by value.' The compiler will issue an error otherwise if changing a capture-by-value variable is attempted.

throw(): A lambda expression may optionally include an exception specification after the parameter list and before the return type specification. The parameter list is necessary if there is an exception specification.

The following lambda expressions specify that they do not throw exceptions:


[](int x) throw() -> bool {return x*7==0;}

[]() throw() {return rand();}

return_type can be omitted if return type is void or code is simply “return expr;”

{body} is simply a block of code.

If my quick reference is not enough – you can see the standards paper with all the details http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf (starting page 87.)

For more complete information about compiler optimizations, see our Optimization Notice.
Tags: