【问题标题】:returning lambda that captures reference [duplicate]返回捕获引用的 lambda [重复]
【发布时间】:2020-05-01 21:55:13
【问题描述】:

在 Cpp 入门第 5 版中。第393页

如果函数返回一个 lambda,那么 - 出于同样的原因 函数不能返回对局部变量的引用——那个 lambda 不得包含引用捕获。

#include <iostream>
using namespace std;

auto foo(ostream &os) {
    auto f = [&os]() -> std::ostream& { os << "Hello World !" << endl; return os;};
    f();
    return f;
}
void main() {
    foo(cout);
    auto f = foo(cout);
    system("pause");
    f();
}

此代码在 msvc 2019 中编译时没有警告。它似乎也运行良好。捕获的os 引用了std::cout,它存在于foo 的范围之外。 f() 是未定义的行为吗?如果是,auto f = foo(cout); 是否也是未定义的行为(即 lambda 的返回和分配)?

【问题讨论】:

  • 只要捕获的变量和 lambda 一样长,我认为没问题。
  • 捕获的变量是os,我认为是对cout 的本地引用。它比 lambda 寿命长,我想,我可能错了
  • 据我所知,定义的行为,只要在销毁 lambda 捕获的实例后不调用您的 lambda(并且实际上尝试使用它),您就可以开始
  • 我将其改写为:不得包含对局部变量的引用
  • 我发现了一个副本,它与您的示例基本相同。它通过引用而不是流来捕获 int。

标签: c++ c++11 lambda


【解决方案1】:

我不是 C++ 专家,但是当您返回一个通过引用捕获局部变量的 lambda 并且该局部变量被丢弃时,您会遇到问题。这是因为捕获的变量不再存在,因此您无法访问它。您提供的示例有点不同,因为您通过引用获取参数,因此当函数返回时它可能仍然存在。这可能仍然很危险,因为您无法知道是否有人传入参数来获取 lambda,然后销毁作为参数传递的变量,最后调用 lambda,因为现在 lambda 可能想要使用捕获的变量,但现在它不再存在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多