未指定Lambda函数的返回类型时出现段错误

Ren*_*sch 6 c++ lambda c++11

我有以下示例代码:

#include <functional>
#include <iostream>
#include <string>

void f(std::function<const std::string&()> fn) {
  std::cout << "in f" << std::endl;
  std::cout << "str: " << fn() << std::endl;
}

int main() {
  std::string str = "a";

  auto fn1 = [&]() { return str; };
  auto fn2 = [&]() { const std::string& str2 = str; return str2; };
  auto fn3 = [&]() -> const std::string& { return str; };

  std::cout << "in main" << std::endl;
  std::cout << "fn1: " << fn1() << std::endl;
  std::cout << "fn2: " << fn2() << std::endl;
  std::cout << "fn3: " << fn3() << std::endl;

  f(fn1);  // Segfaults
  f(fn2);  // Also segfaults
  f(fn3);  // Actually works

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我第一次写这篇文章时,我希望fn1()在内部调用f()将正确返回对strin 的引用main。鉴于这str是分配,直到f()返回后,这在我看来很好。但是实际上发生的是尝试访问fn1()内部段错误的返回f()

发生相同的事情fn2(),但令人惊讶的是它fn3()可以正常工作。

由于fn3()工作和fn1()不,是有什么我缺少有关如何C ++演绎的拉姆达函数的返回值?那将如何创建此段错误?

作为记录,如果运行此代码,则为输出:

仅致电f(fn3)

in main
fn1: a
fn2: a
fn3: a
in f
str: a
Run Code Online (Sandbox Code Playgroud)

仅致电f(fn2)

in main
fn1: a
fn2: a
fn3: a
in f
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

仅致电f(fn1)

in main
fn1: a
fn2: a
fn3: a
in f
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

Oli*_*liv 8

没有尾随返回类型的lambda,如下所示:

[&](){return str;};
Run Code Online (Sandbox Code Playgroud)

等效于:

[&]()->auto{return str;};
Run Code Online (Sandbox Code Playgroud)

因此,此lambda返回str的副本。

调用该std::function对象将得到以下等效代码:

const string& std_function_call_operator(){
    // functor = [&]->auto{return str;};

    return functor();
    }
Run Code Online (Sandbox Code Playgroud)

调用此函数时,str将其复制到一个临时文件中,将引用绑定到该临时文件,然后销毁该临时文件。因此,您将获得著名的悬挂参考。这是一个非常经典的场景。

  • gh,很容易做到。顽皮的C ++! (2认同)