16 July 2022

C++ 核心指南目录

“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 且非局部的地方。标记警告。