C++11/14 – Lambdas

C++11/14 – Lambdas

Introduction

“Lambda” expressions are a part of an effort in C++11 to introduce more “functional programming“-like features to the C++ language.

Normally when we write shared code that needs to take advantage of slightly different, specific behavior we would do one of a few things:

  1. Inheritance – Define the common functionality in the base class, and implement the specific behavior in the derived class as a virtual function.
  2. Callback function – Write the common functionality, and invoke a callback (c-style or std::function) for the specific behavior.

Lambdas are an improvement on option #2, the callback function. Currently callback functions have one slightly awkward drawback. To use callbacks, you need to first create a fully declared/defined C++ function. In some cases this is completely unnecessary, as the function is only used within the context of the callback. It is here that “lambdas” make their entrance. Put simply, lambdas are a syntax extension that lets you create a C++ style callback from a simplified, unnamed function definition. ¬†When you first take a look at the syntax it can be a little bit overwhelming, so I’ll try my best to break it down into simple pieces, with simple explanations.

Syntax

[Captures] ->ReturnType (params) { body }

  • Captures – This is a means of “capturing” variables, pointers, and references declared in the containing scope of the lambda declaration. This lets you forward variables into the lambda’s scope, preserving name, type, const-ness, etc. You can also differentiate per argument whether to capture by copy or reference. In my opinion the most useful thing we can do with these is “default capture” any variable used from the containing scope of the lambda. For a lambda declared in scope of variables “foo”, and “bar”, the capture syntax is as follows:
    • [foo] – Capture just foo by copy into the lambda.
    • [foo, &bar] – Capture foo by copy, and bar by reference into the lambda.
    • [=] – Capture anything used within the lambda by copy.
    • [&] – Capture anything used within the lambda by reference.
    • [] – Capture nothing.
  • “->ReturnType” – This syntax lets us specify the return type of the lambda. Generally it is not required, as the return type can usually be inferred by the compiler. According to the standard the compiler is not required to determine the return type of a lambda if there are more than one return statements in your function. This is the most likely situation where you would encounter the syntax. It should also be noted, if you think this syntax looks weird.. well it is not just a quirk of lambdas. C++ functions can also be written with this “trailing return” if the function uses the “auto” keyword for its return type.
  • Params – This one is obviously your parameter list, akin to a normal function call.
  • Body – Again, just your typical function body.

Leave a Reply

Your email address will not be published. Required fields are marked *