在C ++ 11中使用lambda默认捕获值([=]
)或引用([&]
)会有什么陷阱?
我知道一些陷阱:
按值划分的默认值是否有任何缺点?
答案 0 :(得分:7)
我认为你提到的悬空参考问题是主要的陷阱。
有时候忽略的另一件事是,即使在成员函数中使用了按值捕获的lambda,它也不会创建使用过的成员变量的副本,但只能创建一个this
指针的副本。
首先,这意味着你再次对悬空指针问题开放问题,其次,你可能会意外地修改lambda范围之外的变量,即使看起来像,你只是在修改本地副本。
E.g。这将打印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;
}
编辑:
只是为了避免与@Snps所提出的观点相混淆:
如果bar
是bas()
中的局部变量(因此被值捕获),则上述lambda将无法编译,因为by-value-captured-variables默认为const,除非您明确指定lambda是可变的。
因此,如果您考虑一下,很明显条形图不会被复制,但在阅读或编写代码时很容易被遗忘。
答案 1 :(得分:3)
与以下方面的比较具有完全相同的优点和缺点:
int value(const T x) { ... }
int value(T& x) { ... }
答案 2 :(得分:3)
使用 hbspt.forms.create({
css: '',
cssClass:'.hs-form fieldset {max-width: 100%;}',
portalId: '',
formId: '',
inlineMessage: '<iframe style="width:100%; height:800px;" scrolling="auto" src="URL goes here"></iframe>',
onFormSubmit: function(){
mmConversionTag(704048, this, "_self");
ga("send","event","button","click","product distributors");
}
});
或[=]
按值捕获可以创建与捕获的实体完全相同的的lambda成员,包括constness ,例如,当按值捕获[<identifier>]
时,即使lambda调用运算符是可变的,结果成员也可以不变异。
const int
这可以使用C ++ 14初始化捕获表达式来解决:
const int i = 1;
[=] () mutable { ++i; }(); // Error: increment of read-only variable.
答案 3 :(得分:1)
按值捕获涉及复制关闭的值,因此可能意味着更多的内存消耗和对该副本的更多处理。