标准函数的lambda捕获

问题描述 投票:0回答:1

以下代码导致 分段故障但我不明白为什么。

#include <iostream>
#include <vector>
#include <functional>
class State {public:int x; int y; State(int _x,int _y):x(_x),y(_y){}};
typedef std::function<bool (const State &s)> FuncT;
std::vector<FuncT> funcs_outside;
class Manager
{
    private: std::vector<FuncT> funcs;
    public:  void insert(const FuncT &g){funcs.push_back(g);}
    // public:  void insert(const FuncT &g){funcs_outside.push_back(g);}
    public:  FuncT getAnd()
    {
        // this should capture everything, no?
        return [=](const State &s)
        {
            bool b=true;
            for (const auto f:funcs)
            // for (const auto f:funcs_outside)
            {
                b = b && f(s);
            }
            return b;
        };
    }
};
FuncT foo(void)
{
    Manager m;
    m.insert([=](const State &s){return s.x<=s.y;});
    m.insert([=](const State &s){return s.x>=s.y;});
    return m.getAnd();
}
int main(int argc, char **argv)
{
    auto h = foo();
    std::cout << "h(3,3) = " << h(State(3,3)) << "\n";
    std::cout << "h(3,4) = " << h(State(3,4)) << "\n";
    std::cout << "h(7,2) = " << h(State(7,2)) << "\n";
    return 0;
}
  • 这个... [=] 应该能捕捉到lambda需要的任何东西吧?
  • 当我把 funcsfuncs_outside, 万事如意.
  • 我到底做错了什么?
c++ lambda closures copy-constructor std-function
1个回答
1
投票

我做错了什么?

getAnd 从成员函数中返回一个函数对象,它捕获和访问成员。

你在一个局部变量上调用该成员函数,并将结果的函数对象返回到作用域外。函数对象指向的成员已经不存在了,调用函数对象的结果是未定义的行为。

当我用funcs_outside替换funcs时,一切都很好。

funcs_outside 是一个全局对象,你在它的生命周期内访问它,所以没有问题。

我如何解决这个问题?

例如,你可以捕捉一个成员的副本来代替。

return [funcs = this->funcs](const State &s)
© www.soinside.com 2019 - 2024. All rights reserved.