std 函数的 lambda 捕获

lambda capture of std function

以下代码导致段错误,但我不明白为什么:

#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;
}

What am I doing wrong?

getAnd returns 来自成员函数的函数对象,它捕获和访问成员。

您在局部变量上调用该成员函数,并且 return 生成的函数对象位于范围之外。函数对象指向的成员不再存在,调用函数对象会导致未定义的行为。

When I replace funcs with funcs_outside, everything works well.

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

how can I fix this?

例如,您可以捕获成员的副本:

return [funcs = this->funcs](const State &s)