CppCoreGuidelines F.53 如果不在局部使用(返回、存在堆中、传入另一个线程),不要从 lambda 返回引用
16 July 2022
“Avoid capturing by reference in lambdas that will be used non-locally, including returned, stored on the heap, or passed to another thread”
理由:
局部变量的指针和引用的生存期不能超过其作用域范围。lambda 以引用捕获的变量只是变量的一个别名,超出了变量的作用域范围,变量存储空间已经回收,这时候,它的值可能已经被别的数据覆盖了。
错误的例子:
int local = 42; // Want a reference to local. // Note, that after program exits this scope, // local no longer exists, therefore // process() call will have undefined behavior! thread_pool.queue_work([&] { process(local); });
正确的例子:
int local = 42; // Want a copy of local. // Since a copy of local is made, it will // always be available for the call. thread_pool.queue_work([=] { process(local); });
强化:
- (简单)如果 lambda 的变量捕获列表里有局部声明的变量,警告。
- (复杂)如果 lambda 的变量捕获列表里有局部声明的变量,并且 lambda 传递给了非 const 且非局部的地方。标记警告。