C++生产者消费者模拟:如何在Lambda表达式中传递类成员变量?
问题解析与解决方案
问题根源
在类成员函数的Lambda表达式中,直接访问类私有成员storage失败,核心原因是:
- 类成员变量的本质是通过
this->storage访问的,默认情况下Lambda不会捕获当前对象的this指针,因此无法识别storage标识符。 - 你尝试的
[&storage]捕获方式无效,因为storage不是局部变量,而是类成员,必须通过this指针才能正确引用。
解决方案
要让Lambda访问类成员,有两种可靠的实现方式:
1. 显式捕获this指针
在Lambda的捕获子句中加入this,这样就能在Lambda内直接使用storage(等价于this->storage),这是最通用的方式:
修改后的publish函数:
void publish(int x) { unique_lock<mutex> storageUniqueLock(storageMutex); // 捕获this,简化条件判断逻辑 storageConditionVariable.wait(storageUniqueLock, [this]() { return storage.size() < 50; }); storage.push_back(x); storageConditionVariable.notify_one(); }
修改后的consume函数:
int consume() { unique_lock<mutex> storageUniqueLock(storageMutex); // 捕获this,用empty()更直观高效 storageConditionVariable.wait(storageUniqueLock, [this]() { return !storage.empty(); }); int returnVal = storage.back(); storage.pop_back(); storageConditionVariable.notify_one(); return returnVal; }
2. 显式捕获成员变量的引用(C++14及以上)
如果你不想捕获整个this指针,可以直接捕获storage的引用,需要通过this明确指定成员:
// publish中的Lambda示例 storageConditionVariable.wait(storageUniqueLock, [&storage = this->storage]() { return storage.size() < 50; });
额外优化点
- 简化条件判断:生产者等待的条件是「存储区未满」,直接返回
storage.size() < 50即可,无需冗余的三元表达式;消费者等待的条件是「存储区非空」,用!storage.empty()比storage.size() > 0更直观高效。 - 完善线程等待逻辑:主函数中记得
join消费者线程,否则程序可能提前退出:
int main() { ProducerConsumerSimulation simulationObject; thread publisherThread(publishMethod, std::ref(simulationObject)); thread consumerThread(consumeMethod, std::ref(simulationObject)); publisherThread.join(); consumerThread.join(); // 新增该行,等待消费者线程完成 }
内容的提问来源于stack exchange,提问作者Neer Patel
相关产品推荐
相关产品推荐

