лямбда-захват стандартной функции - PullRequest
0 голосов
/ 04 мая 2020

Следующий код вызывает ошибку сегментации , но я не могу понять, почему:

#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;
}
  • [=] должен захватывать все, что нужно лямбде, верно?
  • Когда я заменяю funcs на funcs_outside, все работает хорошо .
  • Что я делаю не так?

1 Ответ

1 голос
/ 04 мая 2020

Что я делаю не так?

getAnd возвращает объект функции из функции-члена, которая захватывает и обращается к членам.

Вы вызываете эту функцию-член на локальную переменную и вернуть полученный объект функции за пределы области видимости. Элементы, на которые указывает объект функции, больше не существуют, и вызов объекта функции приводит к неопределенному поведению.

Когда я заменяю funcs на funcs_outside, все работает хорошо.

funcs_outside - это глобальный объект, и вы обращаетесь к нему в течение его времени жизни, поэтому проблем нет.

как я могу это исправить?

Вы можете, например, захватить вместо этого копия члена:

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