Open In App

Lambda Capture of *this in C++17

Last Updated : 31 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In C++, a lambda function can capture variables from the enclosing scope using capture clauses. Lambda functions can also be used to capture this pointer, which allows us to access class members and methods within the lambda. In this article, we will learn how Lambda Capture of *this pointer is changed in C++17.

What is Lambda Capture?

Before looking into *this capture, let’s see how lambda capture works in C++. In C++, lambdas are a way to create anonymous functions, which can capture variables from their enclosing scope. There are two primary capture modes: by value and by reference.

Capturing *this in C++ 17

Earlier, we could only capture this pointer by reference. This leads to problems when the referenced object is temporary or goes out of scope leading to the dangling reference. The capture of *this by value was added in C++ 17 to avoid these problems.

In lambda capture of *this, the copy of the object pointed by this pointer is captured and it does not deleted when this object goes out of scope.

This means that the lambda gets its own copy of *this, allowing modifications without affecting the original object. Here, the usage of a mutable keyword is necessary to capture *this by value. Call by value capture of *this is important for asynchronous dispatch of closures, which in turn is a building block of concurrency and parallelism.

Syntax

We just have to define the capture clause of lambda expression like this:

[*this]

Example

C++




// C++ Program to illustrate by value capture of *this
// in lambda expressions
#include <iostream>
using namespace std;
  
class Counter {
public:
    Counter()
        : count(0)
    {
    }
  
    void Increment()
    {
        // Define a lambda that captures *this by value
        auto incrementLambda = [*this]() mutable {
            // Access the count member variable and
            // increment it
            count++;
        };
  
        // Call the lambda to perform the increment
        incrementLambda();
    }
  
    int GetCount() const { return count; }
  
private:
    int count;
};
  
int main()
{
    // Create an instance of the Counter class
    Counter counter;
  
    // Call the Increment method, which uses a lambda to
    // increment the count
    counter.Increment();
    counter.Increment();
  
    // Retrieve and print the updated count
    cout << "Count: " << counter.GetCount() << endl;
  
    return 0;
}


Output

Count: 0

Explanation

In this example, we have a Counter class with a private member variable count, a method Increment that captures *this by value, and a method GetCount to retrieve the current count. Inside the Increment method, we declare a lambda function and capture *this by value using [*this]. This means the lambda gets its own copy of *this and can modify the count without affecting the original object. We call the Increment method twice, and the lambda increments its copy of the count each time. Finally, we retrieve and print the count, which is 0, since the original count was never changed.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads