Создайте непостоянный указатель на функцию-член для фильтрации событий SDL.

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

Есть ли какой-нибудь трюк С++ 11, который я могу использовать для этой работы?

class ObjectWithState
{
    int someState;

public:    
    int operator()(void* userData, SDL_Event *event)
    {
        return ++someState;
    }
};


int main()
{
    //boilerplate
    ObjectWithState obj;

    SDL_EventFilter f = &(obj.operator()); //ERROR -> cannot create non-constant pointer to member function
    SDL_SetEventFilter( f, nullptr );
}

person learnvst    schedule 12.11.2013    source источник
comment
Не связано: ваш operator() на самом деле не возвращает int, как было объявлено.   -  person Casey    schedule 13.11.2013
comment
Ага, извините, упрощение ситуации   -  person learnvst    schedule 13.11.2013


Ответы (2)


Используйте параметр userdata, чтобы указать на ваш объект, и отправьте статический метод нестатическому методу:

class ObjectWithState
{
    int someState;

public:    
    int operator()(SDL_Event *event)
    {
        ++someState
    }

    static int dispatch(void* userdata, SDL_Event* event)
    {
        return static_cast<ObjectWithState*>(userdata)->operator()(event);
    }
};


int main()
{
    //boilerplate
    ObjectWithState obj;

    SDL_SetEventFilter(&ObjectWithState::dispatch, &obj);
}
person Casey    schedule 12.11.2013

Вы не можете назначить указатель на функции-члены указателям на функции в стиле C. Вы должны использовать бесплатную функцию или статическую функцию, а затем вызывать внутри нее любые члены, которые вам нужны.

На самом деле, std::bind может позволить вам это сделать. Хотя не совсем уверен.

person Tony The Lion    schedule 12.11.2013