Могут ли функции принимать статические указатели на функции в качестве аргументов? - PullRequest
2 голосов
/ 30 декабря 2011

Вот хороший пример: я пытаюсь перегрузить OpenGL glutMouseFunc, чтобы он мог принять пространство имен и функцию класса по своему выбору. В частности, это Init::DisplayInit::mouse, который является статическим. Вопрос в том, возможно ли это? Если да, то как это достигается?

Моя реализация

void glutMouseFunc(void (Init::DisplayInit::*mouse)(int, int, int, int)) {
    (*mouse);
}

Ошибки в реализации

..\OpenGL_03\/displayinit.h:27: error: variable or field 'glutMouseFunc' declared void
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: expected primary-expression before 'int'
..\OpenGL_03\/displayinit.h:27: error: void value not ignored as it ought to be

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

Ответы [ 2 ]

5 голосов
/ 30 декабря 2011

Это не разумный способ определить glutMouseFunc.Он не должен вызывать обратный вызов немедленно, он должен сохранить указатель для последующего использования (когда активна мышь).

Вызвать предоставленную GLUT версию и передать адрес вашей функции:

#include <GL/glut.h>
glutMouseFunc(&Init::DisplayInit::mouse);

Статические функции-члены совместимы с обычными указателями функций.

4 голосов
/ 30 декабря 2011

Ответ на вопрос заголовка: «Да; функции могут принимать статические указатели функций в качестве аргументов».

Вы не указываете пространство имен или класс в указателе на спецификацию аргумента функции в функции, использующей его.:

void glutMouseFunc(void (*mouse)(int, int, int, int)) {
    (*mouse)(1, 2, 3, 4);
}

Вы указываете пространство имен или класс в вызове функции:

glutMouseFunc(Init::DisplayInit::mouse);
...