【发布时间】:2014-04-14 18:08:54
【问题描述】:
对于 lambda,我想通过引用捕获一些已经通过引用保存在外部作用域中的东西。假设引用的值超过 lambda,但不是创建 lamdba 的范围。
I know that 如果 lambda 按值 捕获引用变量,则将复制引用的对象。我想避免这个副本。
但是如果我通过引用捕获一个引用变量会发生什么?如果原始引用变量在执行 lambda 之前超出范围怎么办?这安全吗?换句话说:是在引用后面的object被引用还是在lambda中引用了引用变量?
auto f() {
const auto & myRef = g();
return [&]{ myRef.doSomething(); };
}
f()(); // Safe?
【问题讨论】:
-
我不相信。除了理论上,实现
[&]的一种有效方法是存储堆栈深度,并在 lambda 主体中硬编码偏移量。这会将您的状态减少到一个指针,而不是每个变量一个。至于这是一个合法的实施,我想我在其他地方看到了关于 SO 的论点。哦,注意参考延长寿命的危险。作为解决方案,按值捕获引用包装器? -
@dyp,假设 g 返回对长期对象的引用。如 OP 中所述。
-
另一种解决方法:
auto myRef = std::cref(g()); return [=]{ myRef.get().doSomething(); } -
@leemes
[&myRef = myRef]应该没问题。这会在闭包中创建一个引用数据成员。[myRef = *&myRef]执行复制,就像[myRef = myRef]。