Lambda Expressions allow users to write an inline expression that can be used for short snippets of code which are not going to be reused and don’t require naming in your C++ app. The Lambda Expression construct is introduced in C++ 11 and further developed in the C++17 and C++20 standards. Because of its syntax and definition with [ ]
and ( )
and { }
, sometimes it is hard to understand or remember how it works. In this post, we will explain Lambda Expressions step by step.
Now let’s review the Lambda Expression and its syntax.
Table of Contents
What is a Lambda expression?
A Lambda Expression defines an anonymous function or a closure at the point where it is used. You can think of a lambda expression as an unnamed function (that’s why it’s called “anonymous”). Lambda expressions help make code cleaner, more concise, and allow you to see behavior inline where it’s defined instead of referring to an external method, like a function.
Lambda Expressions are an expression that returns a function object. It is well explained here. Lambda expressions are widely used in C++, C#, Groovy, Java, Python, Ruby languages too.
The Greek letter Lambda ( λ ) refers to an anonymous function, it means “chosen” since it is equated with something nameless . The “expression” part of the name means it is ‘required’ since the code can be evaluated and will return a value.
A Lambda Expression is assignable to a variable whose data type is usually auto
and defines a function object.
What is the syntax of a Lambda Expression?
The syntax for a lambda expression consists of specific punctuation with = [ ] ( ) { … } series.
Lambda expressions are one example of modern C++ language features. The aim of this article is to provide information about Lambda Expressions, parts of the expressions, and how they can be used while writing code.
What is the basic syntax of a Lambda Expression in C++ 17?
1 2 3 |
Datatype Lambda Expression = [Capture Clause] (Parameter List) -> Return Type { Body } |
What is the syntax of Lambda Expressions for the C++20 version?
1 2 3 |
Datatype Lambda Expression = [Capture Clause] <Template Parameters> (Parameter List) Specifier Exception Attribute -> Return Type { Body } |
Here;
- Datatype is its type like int, float, class, etc. and mostly auto term is used
- Lambda Expression is a definition by the user
- Capture Clause has variables that are visible in the body, capture can happen by value or reference and it can be empty
- Parameter List can be empty or omitted
- Return Type is a data type returned by the body, optional, normally deduced
- Body contains the programming statements to execute and it can be empty
Lambda Expressions have some advantages and disadvantages, now lets see them.
What are the pros of using Lambda expressions in your C++ app?
Lambda expressions are lightweight, nameless functions that can be defined just-in-place where they are used. Lambdas expression feature is not a specific-purpose feature like functional programming etc. Lambda expressions allow you to specify function arguments as lambdas beside C-like functions and functors. Unless you need a function available in more than one place, you’ll feel more comfortable using lambdas as arguments of STL components. Because of their features, Lambda Expressions have some advantages;
- Lambdas are cheap in memory and CPU usage. The cost of a lambda expression is never greater than the cost of an equivalent class or function.
- They are some like identical to using a class. Their assembly output is identical to using a class
- Lambdas allocate on the stack, not heap, this may an advantage in some cases
- We don’t need to capture static variables when using Lambdas
- We can return a lambda. We can use
std::function
or similar - In Lambda Expression, captured variables are immutable by default
- Copying a lambda expression, will copy its state
- Capturing
this
in Lambda Expression is not a special case - Lambda Expressions are also cheap, If you do capture a variable. The cost is the same as constructing an object and calling a function directly on it, with no virtual look-ups.
What are the cons of using Lambda expressions in a C++ app?
Since the lambda expressions has been introduced in C++11 standards (2011) – as it that allow you to write an inline, anonymous functor to replace the struct f
– still it is not popular in C++ usage among the developers. I try to list some of the reasons, and its disadvantages below,
- Developers find Lambda expressions are complex to use
- Hard to remember its syntax. Developers think its syntax is confusing, its notations too.
- Hard to understand what is behind the lambda definition (in a struct way or in assembler programming)
- New developers may get difficulties to adopt to their new code lines including those lambda definitions
- Developers may mistake ‘=’ and ‘&’ capture symbols. In some cases, detecting this problem may take a lot of time. These kind of problems can be found by variable changes in steps of debugging only. ( Note that & symbol in capture points the address of variable, means value of variable in usage; = symbol in capture points the exact value of variable in definition)
- Global and local usage of lambda definitions with capture types may have errors in wrong usages
- Lambdas allocate on the stack, not heap, this may be disadvantage in some cases
- If a developer don’t capture any variables, Lambda Expressions are literally like a function call, which means they are cheaper in this type.
- There is a common misconception about captures that some developers may think [=] and [&] capture all surrounding variables. Actually this is wrong ! They only capture every variable that is used in the function definition, and no more. Developers should explicitly name each captured variable however.
- If a lambda will generate a class, it will be as expensive as creating an equivalent class that holds the same number of variables as you capture. If you capture the more variables (particularly by value), the larger your generated functor class, and the more expensive your use of a lambda will be. In addition, if you capture by reference generally, this will be no more than a few pointers.
C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.