Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Lambda Functions Are Ready for Prime Time-3 : Page 3




Application Security Testing: An Integral Part of DevOps

External References

Roughly speaking, lambda expressions are divided into two categories: those with external references and those with no external references. What it's all about? Lambda expressions with external references access variables defined outside the lambda expression's parameter list. By contrast, lambda expressions with no external references don't access variables defined outside the lambda expression's parameter list. Here's a lambda expression with no external references:

[](int x, int y) -> int { return x + y; }

And here's one with external references:

//Note: pseudo C++ code int z; myfunc([](int x, int y)->int {return x + y + z;});

The last lambda accesses the variable z which is declared outside the lambda expression. In cases like this, the referenced external variable must be represented in the closure somehow. There are two ways in which C++ can store variables with external references in the closure:
  • Store a copy of z in a data member.
  • Define a reference data member and bind it to z.
You instruct the compiler which type of representation you want—copy or reference—by providing a lambda capture. A lambda capture is a description of the environment that the lambda expression will access, where the environment is the closure's data members. The capture appears between the brackets of the introducer. There are several types of captures but I'll demonstrate only two of them:
  • The default capture [=] indicates that, by default, closure copies the values of the external variables into its private data members.
  • The default capture [&] indicates that, by default, closure contains reference variables bound to the external variables.
Following this discussion, you now know that the correct syntax for the last lambda expression is either:

int z; myfunc([=](int x,int y)->int {return x + y + z;});


int z; myfunc([&](int x,int y)->int {return x + y + z;});

Depending on whether you want the closure to store a copy of z or a reference to it, respectively.

Getting back to the original example, you can tell what the role of the [&] in the following lambda is:

double min_salary = 1000; double upper_lmt = 1.5 * min_salary; std::find if(emps.begin(), emps.end(), [&](const employee& emp) (emp.salary() >= min_salary && emp.salary()&lr upper_lmt));

The body refers to the variables min_salary and upper_lmt, which are declared independently of the lambda expression. The lambda introducer contains the & capture which instructs the compiler to create reference data members that are bound to min_salary and upper_lmt. As you can see, lambda functions are likely to simplify your code.

At the time of writing, several compilers including Visual C++ 10 (beta) and Intel C++ 11.0 already support lambdas. Others are soon likely to follow suit

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date