20

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

他的实现相当简单(除了需要concurrent_queueMicrosoft 的 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 捕获如何处理类成员变量?没有人在对视频的评论或谈话中说任何话,所以我假设我的理解是错误的,在这种情况下,有人可以澄清一下吗?

4

1 回答 1

37

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

于 2013-06-19T17:55:35.323 回答