std::thread构造时lambda捕获需谨慎:引用捕获易致悬垂,应优先值捕获[=]或显式捕获;移动-only类型须用[p=std::move(p)]初始化捕获;thread对象析构前必须join()或detach(),否则terminate()。

std::thread 构造时直接传入 lambda,必须注意值捕获还是引用捕获
lambda 作为线程函数最常见也最容易出错的地方,在于捕获方式和变量生命周期不匹配。线程可能在 lambda 捕获的局部变量已销毁后才执行,尤其是使用 [&] 引用捕获时。
正确做法是:除非明确知道被引用对象在线程整个生命周期内有效(比如全局变量、静态变量或主线程中长期存活的对象),否则一律优先用值捕获 [=] 或显式值捕获 [x, y]。
-
std::thread t([&]{ do_something(x); });—— 危险!若x是栈上局部变量,t启动前x可能已被析构 -
std::thread t([=]{ do_something(x); });—— 安全(前提是x可拷贝);x在构造t时被拷贝进 lambda 闭包 - 若需移动语义(如捕获
std::unique_ptr),必须用[ptr = std::move(ptr)]显式移动,不能依赖[=]
lambda 捕获 move-only 类型(如 std::unique_ptr)需要显式移动绑定
lambda 默认按值捕获会尝试拷贝,而 std::unique_ptr 不可拷贝。直接写 [ptr]{ ... } 会导致编译错误:call to implicitly-deleted copy constructor。
解决方法是用初始化捕获(C++14 起支持,但 C++11 编译器如 GCC 4.9+ 也常支持该扩展),显式移动:
std::bind
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











