Lambda捕获和成员变量

Lambda captures and member variables

本文关键字:成员 变量 Lambda      更新时间:2023-10-16

我看了Herb Sutter在2012年c++ and Beyond并发会议上的演讲,他谈到了用c++ 11函数创建一个非阻塞包装器类,他称之为concurrent<T>

他的实现是相当简单的(除了需要一个concurrent_queue,如存在于微软的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); } ); }
};

这似乎很简单,然而,我很困惑,为什么他捕获了成员变量doneq的值,而不是通过引用?我的理解是,如果它们是按值捕获的,那么它们将被复制到线程,因此,当队列更新时,工作线程将不会收到更新?

我是否误解了lambda捕获关于类成员变量的工作方式?没有人在视频或演讲的评论中说什么,所以我假设我的理解是错误的,在这种情况下,有人能澄清吗?

成员变量永远不能按值捕获。通过值捕获的是用于访问它们的隐式this指针。因此,它是按值捕获指针,这意味着它通过引用捕获该对象(及其成员)。