Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda captures and member variables

Tags:

I was watching Herb Sutter's talk at the C++ and Beyond 2012 conference on Concurrency and he talks about creating a non-blocking wrapper class, which he calls concurrent<T>, with C++11 functions.

His implementation is fairly simple (aside from needing a concurrent_queue such as that which exists in Microsoft's PPL):

template <class T>
class concurrent {
private:
    mutable T t;
    mutable concurrent_queue<std::function<void()>> q;
    bool done = false;
    std::thread thread;

public:
    concurrent( T t_ = T{} ) : t{t_}, thread{ [=]{ while( !done ) q.pop()(); }} {}

    ~concurrent() { q.push( [=]{ done = true; } ); thread.join(); }

    template <typename F>
    void operator()( F f ) const { q.push( [=]{ f(t); } ); }

};

This seems simple enough, however, I'm confused as to why he has captured the member variables done and q by value instead of by reference? My understanding is that if they are captured by value then they will be copied to the thread and thus when the queue is updated the worker thread will not receive the updates?

Have I misunderstood how lambda captures work with regards to class member variables? No one said anything in the comments to the video or during the talk so I am assuming that my understanding is faulty, in which case could someone please clarify?

like image 859
Thomas Russell Avatar asked Jun 19 '13 17:06

Thomas Russell


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 are lambda captures?

Captures default to const value. By default, variables are captured by const value . This means when the lambda is created, the lambda captures a constant copy of the outer scope variable, which means that the lambda is not allowed to modify them.

What variables do lambda expressions have access to?

A Lambda expression has access to both instance and static variables of it's enclosing class and also it can access local variables which are effectively final or final.

How many ways we can capture the external variables in the lambda expression?

Explanation: There are three ways in which we can capture the external variables inside the lambda expression namely capture by reference, capture by value and capture by both that is mixed capture.


1 Answers

Member variables can never be captured by value. What's being captured by value is the implicit this pointer used to access them. Therefore, it's capturing a pointer by value, which means it captures this object (and its members) by reference.

like image 131
Nicol Bolas Avatar answered Sep 25 '22 05:09

Nicol Bolas