2011-12-30 5 views
2

Вот хороший пример: я пытаюсь перегрузить 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 

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

+0

Имена в вашем сообщении об ошибке не соответствуют фрагменту кода. Показать фактический код. –

+0

Первая ошибка указывает на то, что компилятор думал, что вы указываете бит поле или около того из-за двоеточия; остальные ошибки указывают на то, что компилятор все еще запутался. –

ответ

5

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

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

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

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

+2

Вам не нужен амперсанд там, не так ли? –

+1

@JonathanLeffler: для свободных функций и статических членов компилятор выяснит, что вы хотите сделать указатель на функцию даже без адреса оператора. Для нестатических элементов требуется амперсанд. Но я всегда ставил амперсанд, чтобы было ясно, что я фактически передаю адрес функции, это просто яснее. Просто потому, что вы можете косвенно принять адрес, это не значит, что вы должны. Аналогично, при вызове функции я предпочитаю использовать '(* func_ptr)()', хотя функция func_ptr() 'также работает. –

4

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

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

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

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

glutMouseFunc(Init::DisplayInit::mouse); 
+0

Я знаю, что вопрос был отменен, но ['glutMouseFunc'] (http://www.opengl.org/resources/libraries/glut/spec3/node50.html) должен установить обратный вызов, а не вызвать предоставленный функция. –

+0

ОК - это было ... непонятно (и требует подробного знания OpenGL - или, по крайней мере, большего знания об этом, чем у меня). Обозначение было скорее вызовом функции, чем назначением, поэтому я преобразовал его в вызов. Если он устанавливает обратный вызов, тогда должно быть что-то вроде 'cb_func_ptr = mouse;' вместо этого. –

Смежные вопросы