存储在容器中的C ++ Lambda"这个"

时间:2016-02-01 01:04:24

标签: c++ c++11 lambda

考虑以下最小代码:

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

class A
{
public:
  A() :
    s("dummy"),
    f([&, this]{ return s == "dummy"; }),
  {}
  std::string s;
  std::function<bool ()> f;
};

int main(int argc, char *argv[])
{
  A a;
  a.f(); // seems fine

  std::vector<A> as({});
  as[0].f(); // segmentation fault
}

A有一个lambda成员,可以捕获this指针。运行上面的代码时,lambda在从独立A实例调用时工作正常,但是当从存储在向量中的实例调用时,我会出现分段错误。

为什么会这样?

1 个答案:

答案 0 :(得分:8)

您的示例有几个不同的问题。这一行

vector

构造一个空的std::vector<A> as; as.emplace_back(); a[0].f(); 。当您索引到下一行的第一个元素时,您有未定义的行为,并且在这种情况下您的程序崩溃。

如果您将其更改为

vector

代码将按预期工作,但这并不意味着没有更多问题。如果向this添加更多元素,它将重新分配存储以容纳新元素,并且先前存储的lambda将构建移动。但是当发生这种情况时,它们仍然会保留旧的class A { public: A() : s("dummy"), f([&, this]{ std::cout << this << '\n'; return s == "dummy"; }) {} std::string s; std::function<bool ()> f; }; int main() { std::vector<A> as; { A a; a.f(); as.push_back(a); // make a copy of a as[0].f(); // this pointer stays the same as the original } // lifetime of a ends as[0].f(); // undefined behavior } 指针值,这些值指向现在已经死亡的对象。之后调用lambda是未定义的行为。

以下是潜在问题的一个例子

LinkedStackADT

Live demo