合理设置 lambda 表达式的捕获方式
8.28 ID_unsuitableCapture
如果 lambda 表达式只在函数内部使用,可采用捕获引用的方式;如果 lambda 表达式可以超出函数作用域,应采用捕获值的方式。
示例:
auto foo() -> function<int()> {
int i = 0;
....
return [&]() { return ++i; }; // Non-compliant
}
例中的 lambda 表达式引用了局部变量 i,但返回后 i 的地址不再有效,会导致标准未定义的行为。
另外,要注意解引用指针造成的间接引用:
class A {
int i = 0;
public:
auto bar() {
return [=]() { return i; }; // Bad
}
};
例中的 lambda 表达式通过值捕获变量,this 指针也被捕获,成员变量 i 是通过 this 指针的隐式解引用获取到的,如果 lambda 表达式在 this 指针的生命周期之外执行,就会造成错误。
应改为:
auto A::bar() {
return [*this]() { return i; }; // OK
}
如果需要捕获 this 指针,则应显式捕获所有相关变量,避免使用“[=]”。
相关
依据
ISO/IEC 14882:2011 5.1.2
ISO/IEC 14882:2017 8.1.5.2