19 April 2023
Lambda functions are a popular feature in modern programming languages, and C++ is no exception. They are a powerful tool for writing concise, easy-to-read code that performs a specific task. In this article, we will explore how to use lambda functions in C++ and their syntax.
What is a Lambda Function?
A lambda function, also known as a lambda expression, is a function that is defined inline with the code that calls it. It is an unnamed function that can be used wherever a function pointer or function object is expected. Lambda functions are commonly used in C++ to define small, one-time-use functions that do not need to be named.
Lambda functions were introduced in C++11 and have since become an essential tool for modern C++ programming. They provide a concise way to define simple functions without having to declare a separate function elsewhere in the code.
Syntax of Lambda Functions
The syntax of lambda functions can be a bit confusing at first, but it is actually quite simple once you understand it. The basic syntax of a lambda function is as follows:
[capture-list] (parameter-list) -> return-type { function-body }
Let's break this down into its individual components:
capture-list
: This is an optional list of variables that the lambda function can access from the enclosing scope. We'll explore capture lists in more detail later in the article.
parameter-list
: This is a comma-separated list of parameters that the lambda function takes as input.
return-type
: This is the return type of the lambda function. If the lambda function does not return a value, void
can be used.
function-body
: This is the body of the lambda function, where the actual code to be executed is defined.
Example of Lambda Functions
Let's look at a simple example of a lambda function to better understand its syntax:
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v{ 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 }; int x = 5; auto is_greater_than_x = [x](int i) { return i > x; }; auto count = std::count_if(v.begin(), v.end(), is_greater_than_x); std::cout << "There are " << count << " elements greater than " << x << std::endl; return 0; }
In this example, we create a lambda function called is_greater_than_x
, which takes an integer i
and returns whether i
is greater than x
. We then use the std::count_if
algorithm from the <algorithm>
library to count the number of elements in a vector v
that satisfy this condition.
The output of this program is:
There are 4 elements greater than 5
Capture Lists
As mentioned earlier, capture lists are an optional component of lambda functions that allow you to access variables from the enclosing scope. There are two types of capture lists in C++: explicit capture and implicit capture.
Explicit capture is done by listing the variables to be captured in the capture list. For example:
int x = 5; auto f = [x]() { std::cout << x << std::endl; };
In this example, we explicitly capture the variable x
by value, meaning that the lambda function will make a copy of x
and use that copy in its code.
A lambda function can also capture values from its surrounding context. This can be done by including the values inside square brackets []
before the lambda function body. For example:
int x = 10; auto lambda = [x]() { std::cout << "Value of x is: " << x << std::endl; }; lambda(); // Output: Value of x is: 10
Here, we have captured the value of x
in the lambda function. When we call the lambda function, it prints the value of x
as 10.
The [x]
in the lambda function is called a capture list. It tells the lambda function to capture the value of x
. We can also capture multiple values by separating them with commas:
int x = 10, y = 20; auto lambda = [x, y]() { std::cout << "Value of x is: " << x << std::endl; std::cout << "Value of y is: " << y << std::endl; }; lambda(); // Output: Value of x is: 10 // Value of y is: 20
By default, the values in a capture list are captured by value. This means that a copy of the value is made and stored inside the lambda function. However, we can also capture values by reference by adding an ampersand &
before the variable name. For example:
int x = 10; auto lambda = [&x]() { x = 20; std::cout << "Value of x is: " << x << std::endl; }; lambda(); // Output: Value of x is: 20 std::cout << "Value of x outside lambda is: " << x << std::endl; // Output: Value of x outside lambda is: 20
In this example, we have captured x
by reference. This means that any changes made to x
inside the lambda function are also reflected outside the lambda function.
In addition to capturing by value and by reference, we can also capture values by move using the double ampersand &&
notation. This is useful when we want to transfer ownership of an object to the lambda function. For example:
std::vector<int> v {1, 2, 3, 4, 5}; auto lambda = [v = std::move(v)]() { for (auto& elem : v) { std::cout << elem << std::endl; } }; lambda(); // Output: 1 2 3 4 5
Here, we have captured the vector v
by move. This means that the ownership of the vector has been transferred to the lambda function, and the original vector v
is now empty.
Lambda functions are a powerful feature in C++ that allow us to create anonymous functions with concise syntax. They can be used in a variety of situations where a small, one-time-use function is needed, such as when using algorithms from the <algorithm>
library or when working with threads.
In this article, we covered the basics of lambda functions in C++, including their syntax, capturing values, and capturing values by reference and by move. With this knowledge, you should be able to use lambda functions in your own code and take advantage of their flexibility and conciseness.
JBI Training offers a number of courses to get you started in C++ or to advanced your knowledge. Our Training courses are taught by expert instructors.
The below documentation provides more in-depth information about the function, including its parameters, return value, and examples of how to use it in different contexts. It is always a good idea to consult official documentation when working with any programming language or library, as it can provide valuable insights and ensure that you are using the function correctly.
C++ Programming Tutorials: This website provides a comprehensive set of tutorials for learning C++, covering topics such as variables, data types, control structures, functions, classes, and more. Each tutorial includes code examples and explanations, making it easy to follow along and learn at your own pace. https://www.tutorialspoint.com/cplusplus/index.htm
C++ Standard Library: The C++ Standard Library is a collection of functions and classes that provide essential functionality for C++ programming. This website provides documentation and examples of how to use the various components of the library, including containers, algorithms, iterators, streams, and more. https://en.cppreference.com/w/cpp
C++ FAQ: The C++ FAQ is a comprehensive resource for answering common questions and issues that arise when working with C++. The website covers a wide range of topics, including language features, programming techniques, performance optimization, and more. https://www.parashift.com/c++-faq/
C++ Concurrency: C++ Concurrency is a library that provides tools and techniques for working with concurrent programming in C++. This website provides documentation and examples of how to use the library, including threading, synchronization, futures, and more. https://en.cppreference.com/w/cpp/thread
C++17: The C++17 standard introduces several new language features and improvements, such as structured bindings, constexpr if, and more. This website provides an overview of the new features and how to use them. https://en.cppreference.com/w/cpp/17
CONTACT
+44 (0)20 8446 7555
Copyright © 2023 JBI Training. All Rights Reserved.
JB International Training Ltd - Company Registration Number: 08458005
Registered Address: Wohl Enterprise Hub, 2B Redbourne Avenue, London, N3 2BS
Modern Slavery Statement & Corporate Policies | Terms & Conditions | Contact Us