在C++ 11 中使用value([=])或reference([&])使用lambda默认捕获有什么缺陷?
我知道一些陷阱,如:
按值划分的默认值是否有任何缺点?
我认为你提到的悬空参考问题是主要的陷阱.
然而,另一件有时被忽略的事情是,即使在成员函数中使用了按值捕获的lambda,它也不会创建使用过的成员变量的副本,而只会创建this指针的副本.
首先,这意味着您再次对悬空指针问题开放问题,其次,您可能会意外地修改lambda范围之外的变量,即使它看起来像,您只是修改本地副本.
例如,这将打印0 1 1而不是0 1 0
struct Foo {
int bar=0;
int bas() {
auto inc = [=]() {
bar++; //this is equivalent to this->bar++
return bar;
};
return inc();
}
};
int main() {
Foo foo;
std::cout << foo.bar <<" ";
std::cout << foo.bas() << " ";
std::cout << foo.bar << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
编辑:只是为了避免与@Snps相关的混淆:
如果bar是一个局部变量bas()(并因此被值捕获),上面的lambda将无法编译,因为by-value-captured-variables默认为const,除非您明确指定lambda为mutable.因此,如果您考虑一下,很明显bar不会被复制,但在阅读或编写代码时很容易被遗忘.
它与以下之间的比较具有完全相同的优点和缺点:
int value(const T x) { ... }
int value(T& x) { ... }
Run Code Online (Sandbox Code Playgroud)
[=]使用or按值捕获具有创建与捕获实体完全相同类型[<identifier>]的 lambda 成员的效果,包括 constness,例如,当按值捕获时,即使 lambda 调用运算符是可变的,结果成员也不能改变。const int
const int i = 1;
[=] () mutable { ++i; }(); // Error: increment of read-only variable.
Run Code Online (Sandbox Code Playgroud)
这可以使用 C++14 的初始化捕获表达式来解决:
[i = i] () mutable { ++i; }(); // Ok
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1907 次 |
| 最近记录: |