Как назначить лямбда-функцию для структуры член, когда функция должна получить доступ к другим членам? - PullRequest
0 голосов
/ 07 апреля 2019

Я хотел бы закодировать указатель вспомогательной функции внутри моего объекта, который вызывает группу других функций в объекте.Этот указатель служебной функции должен быть инициализирован с функциональностью по умолчанию, но также должен иметь возможность переопределения.

Это то, что у меня есть до сих пор:

struct GameState {
    void(*setup)()          = [](){};
    void(*handleInput)()    = [](){};
    void(*update)()         = [](){};
    void(*draw)()           = [](){};
    void(*run)() = [this]() { handleInput(); update(); draw(); };
}

Компилятору не нравится использованиеthis в захвате моей лямбда-функции и выдает следующие ошибки все для этой строки:

E0413 - нет подходящей функции преобразования из "lambda [] void () -> void" в "void (*) () "существует

C2440 'инициализация': невозможно преобразовать из 'GameState ::' в 'void (__cdecl *) (void)'

C2439 'GameState :: run':элемент не может быть инициализирован

1 Ответ

3 голосов
/ 07 апреля 2019

Проблема в том, что типы не совпадают.

void(*run)() = [this]() { handleInput(); update(); draw(); }; }

Вы назначаете лямбду на указатель функции. Лямбда не является указателем на функцию и фактически является экземпляром класса, который переопределяет operator(). Этот объект также фиксирует это в вашем example.

void(*setup)() = [](){};

Компилируется, потому что нет захвата. Когда нет захвата, нет никакого состояния, и лямбда может рассматриваться как указатель, а не как экземпляр класса.

Если бы это было разрешено языком, вы бы хотели что-то вроде

// error
auto run  = [this]() { handleInput(); update(); draw(); };·

Но этот синтаксис не поддерживается в этом контексте. А поскольку тип лямбда-объекта неизвестен программисту, нет возможности записать его тип.

Вместо этого будет работать что-то вроде:

std::function<void()>run  = [this]() { handleInput(); update(); draw(); };

Это не так эффективно, как определение run с типом лямбды, поскольку std::function, скорее всего, будет хранить лямбда в куче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...