2

Here's a good example: I'm trying to overload OpenGL's glutMouseFunc so it may accept the namespace, and class function of my choosing. The one in particular is Init::DisplayInit::mouse, which is static. The question is, is this possible? If so, how is this achieved?

My Implementation

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

Errors from Implementation

..\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

Note, I put the declaration of the function in the same file's header file. I also made sure both the declaration and the definition of the function resided outside of the namespace declaration (which wraps most of both files, each). As shown, one of the first errors reads the function as a variable or field (???).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
zeboidlund
  • 9,731
  • 31
  • 118
  • 180
  • The names in your error message don't match the code snippet. Show the actual code. – Ben Voigt Dec 30 '11 at 02:25
  • The first error indicates that the compiler was thinking that you were specifying a bit field or thereabouts because of the colons; the rest of the errors indicate that the compiler was still confused. – Jonathan Leffler Dec 30 '11 at 02:27

2 Answers2

5

That's not a reasonable way to define glutMouseFunc. It isn't supposed to call the callback immediately, it's supposed to save a pointer for later (when mouse activity occurs).

Call the GLUT-provided version, and pass the address of your function:

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

Static member functions are compatible with ordinary function pointers.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • 2
    You don't need the ampersand in there, do you? – Jonathan Leffler Dec 30 '11 at 02:38
  • 1
    @JonathanLeffler: For loose functions and static members, the compiler will figure out you wanted to make a function pointer even without the address-of operator. For non-static members, the ampersand is required. But I always put in the ampersand, to make it clear that I'm actually passing the address of the function, it's just clearer that way. Just because you can implicitly take the address doesn't mean that you should. Similarly, when calling the function I prefer to use `(*func_ptr)()` even though `func_ptr()` also works. – Ben Voigt Dec 30 '11 at 02:41
4

The answer to the headline question is "Yes; functions can accept static function pointers as arguments".

You don't specify the namespace or class in the pointer to function argument specification in the function using it:

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

You do specify the namespace or class in the invocation of the function:

glutMouseFunc(Init::DisplayInit::mouse);
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I know the question de-emphasized this, but [`glutMouseFunc`](http://www.opengl.org/resources/libraries/glut/spec3/node50.html) is supposed to install a callback, not call the provided function. – Ben Voigt Dec 30 '11 at 02:32
  • OK - that was...not clear (and requires detailed knowledge of OpenGL - or, at least, more knowledge of it than I have). The notation was more nearly a function call than an assignment, so I converted it to the call. If it sets a callback, then there needs to be something like `cb_func_ptr = mouse;` instead. – Jonathan Leffler Dec 30 '11 at 02:37