我在C ++和Beyond 2012关于并发的会议上观看了Herb Sutter's talk,他谈到创建一个非阻塞的包装类,他称之为concurrent<T>
,具有C ++ 11函数。
他的实现相当简单(除了需要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); } ); }
};
:
done
这看起来很简单,但是,我很困惑他为什么用值而不是引用来捕获成员变量q
和{{1}}?我的理解是,如果它们被值捕获,那么它们将被复制到线程中,因此当队列更新时,工作线程将不会收到更新?
我是否误解了lambda捕获如何处理类成员变量?没有人在视频评论或谈话中说什么,所以我假设我的理解是错误的,在这种情况下有人可以澄清一下吗?
答案 0 :(得分:37)
成员变量永远不会被值捕获。值捕获的是用于访问它们的隐式this
指针。因此,它按值捕获指针,这意味着它通过引用捕获此对象(及其成员)。