Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a data member be in a lambda capture list

Tags:

c++

c++11

lambda

I have a class foo that has bar as a member variable.

In another member function of the class, I'm writing a lambda function:

[bar](void){} 

But I can't include bar in the capture list. Why is that?

like image 846
P45 Imminent Avatar asked May 22 '14 09:05

P45 Imminent


People also ask

How do you capture a member variable in lambda?

To capture the member variables inside lambda function, capture the “this” pointer by value i.e. std::for_each(vec. begin(), vec. end(), [this](int element){ //.... }

What is a lambda capture list?

The capture clause is used to (indirectly) give a lambda access to variables available in the surrounding scope that it normally would not have access to. All we need to do is list the entities we want to access from within the lambda as part of the capture clause.

What does it mean to lambda capture this?

The lambda is capturing an outside variable. A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.

Does lambda capture reference by value?

Lambdas always capture objects, and they can do so by value or by reference.


1 Answers

Only objects with automatic storage duration can be captured by a lambda in C++11 (i.e. local variables and function parameters). If you want the effect of capturing a non-static class data member, you can either capture the this pointer as in Danvil's answer:

auto f = [this]{ std::cout << a << std::endl; }; 

or cache the data member's value in a local variable and capture that:

auto a = this->a; auto f = [a]{ std::cout << a << std::endl; }; 

which will be much more concise in C++14:

auto f = [a = this->a]{ std::cout << a << std::endl; }; 

The choice between these two options depends on whether you want to store the value a has right now or if you want to retrieve the value a has when the lambda is called. Note that in the case where this is captured you must ensure that the lifetime of the pointer object encloses the lifetime of the lambda a call to the lambda after the object is destroyed has undefined behavior. The more simple case that captures a copy of a is completely self-contained and has no such lifetime issues.

like image 79
Casey Avatar answered Sep 23 '22 13:09

Casey