Codecademy Logo

Lambda Expressions in C++

Related learning

  • Learn advanced C++ programming with preprocessor directives, operator overloading, streams, and lambda expressions.
    • With Certificate
    • Advanced.
      9 hours

C++ Lambda Functions

Lambda functions in C++ are concise ways to create anonymous functions at runtime. These function objects can capture local variables and are defined inline, avoiding separate function declaration.

#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
int factor = 2;
std::for_each(numbers.begin(), numbers.end(), [factor](int &n) {
n *= factor;
});
for(const auto& num : numbers) {
std::cout << num << " ";
}
return 0;
}

C++ Lambda Expressions

C++ lambda expressions provide a way to define anonymous functions. They consist of a capture clause, an optional parameter list, an optional return type, and a function body. This structure allows you to create succinct and powerful function objects inline. The capture clause [ ] determines the variables to capture from the surrounding scope.

#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
int factor = 10;
auto multiply = [factor](int num) -> int {
return num * factor;
};
for (int number : numbers) {
std::cout << multiply(number) << " ";
}
return 0;
}

C++ Lambda Capture

When writing a lambda function in C++, the capture clause specifies how it accesses variables from its enclosing scope. By listing variables within brackets [ ], you can capture by value, reference, or a mix of both, making your lambda adaptable to its context.

#include <iostream>
#include <vector>
int main() {
int multiplier = 2;
std::vector<int> numbers = {1, 2, 3, 4, 5};
// Lambda to multiply each number by the `multiplier`
auto multiply = [&multiplier](int num) { return num * multiplier; };
for (int num : numbers) {
std::cout << multiply(num) << " ";
}
// Output: 2 4 6 8 10
return 0;
}

C++ Lambda Captures

In C++, lambda expressions can capture variables from their surrounding scope. Captures can be done by value [=], by reference [&], or selectively [x, &y] for each variable. This method determines how each variable is accessed and modified within the lambda.

#include <iostream>
using namespace std;
int main() {
int a = 10;
int b = 20;
// Capture by value
auto lambdaValue = [=]() { return a + b; };
// Capture by reference
auto lambdaReference = [&]() { b = a + b; };
// Capture 'a' by value and 'b' by reference
auto lambdaSelective = [a, &b]() { b += a; };
cout << "Value capture: " << lambdaValue() << endl;
lambdaReference();
cout << "Reference capture affect: " << b << endl;
lambdaSelective();
cout << "Selective capture affect: " << b << endl;
return 0;
}

Lambda Transformations

Lambdas transform data effectively in C++ through concise transformations in algorithms like std::transform. Utilize this compact syntax to map and manipulate elements from one collection to another, streamlining transformations with ease and efficiency.

#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {5, 3, 8, 1, 4};
std::vector<int> doubled(numbers.size());
// Double each number using lambda
std::transform(numbers.begin(), numbers.end(), doubled.begin(), [](int n) {
return n * 2;
});
std::cout << "Doubled numbers: ";
for(auto n : doubled) {
std::cout << n << " ";
}
return 0;
}

C++14 Lambda Updates

C++14 introduced improvements to lambdas, including generic lambdas using auto. This feature decreases the need for duplicating code for different types, enhancing flexibility and reducing verbosity.

#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
int factor = 2;
auto multiply = [factor](auto num) { return num * factor; };
for (auto n : numbers) {
std::cout << multiply(n) << " ";
}
std::cout << std::endl;
return 0;
}

Lambda with Function

Use a std::function object to store C++ lambda expressions for multiple invocations. This method helps manage dynamic tasks and enhances code reusability.

#include <iostream>
#include <functional>
int main() {
// Lambda in std::function
std::function<void()> printMessage = []() { std::cout << "Message executed!" << std::endl; };
printMessage(); // Invoke stored lambda
return 0;
}

Capture Initializer

With capture initializers in C++, you can modify variables before capturing them. This offers flexibility when you’re using lambda expressions and want to manipulate external variables.

#include <iostream>
int main() {
int base = 4;
auto computeWithBase = [baseValue = base * 2](int num) {
return baseValue + num;
};
std::cout << computeWithBase(10); // Output: 18
}

Learn more on Codecademy

  • Learn advanced C++ programming with preprocessor directives, operator overloading, streams, and lambda expressions.
    • With Certificate
    • Advanced.
      9 hours