Argument of type '(Foo::)(int,int)' does not match 'void (*)(int,int)' in main.cpp
I want to pass Resize method of my Foo class object as the argument of glutReshapeFunc() but I get that error. How should I pass it?
This is my definition of Resize:
class Foo{
public:
void Resize(int w, int h);
...
}
and this开发者_Python百科 is how I try to call it
glutReshapeFunc(foo->Resize);
It was ok when foo was not a pointer, I use to pass foo.Resize and it worked.
Thanks in advance
Non-static functions take an additional hidden parameter (this
) so they're not compatible with a global, non-member, function with apparently similar signature.
You could make Resize
a static, but you'll have problem figuring out on what object to act. glutReshapeFunc
mentions that
Before the callback, the current window is set to the window that has been reshaped.
so you can start from there in your static member.
foo->Resize
by itself is not a valid expression in C++. So, your code is flat out invalid. The only way to obtain a pointer to a non-static member function in C++ is to explicitly use the &
operator and to explicitly use the qualified name of the member function. In your case that would be &Foo::Resize
.
However, this is all beside the point, since you apparently need a pointer to an ordinary function not to a member function. A pointer to a member function is an object of completely different nature not even remotely similar to a pointer to an ordinary function. In other words, what you are trying to do is impossible. You can't pass a pointer to your Foo::Resize
to glutReshapeFunc
regardless of what you do.
If you want to call a non-static member function as a callback, it is your responsibility to use some kind of intermediate wrapper function that will receive the call and delegate it to the member function through a proper object. C++ by itself provides no good features for that, but it often can be implemented using specific features of the library you are trying to use (assuming the library is designed with that in mind).
What you need is to map the current window to the foo object that represents that window (assuming you have one foo object per Window).
If you only have one foo object or you think of making the method static then stop. This is a C library and thus des not understand the C++ ABI. Switch your code back to using C functions. If your code is written in C++ files (or compiled as C++) then you must declare the functions as extern "C" to make sure that the bindings are correct.
If you have a Foo object for each window then I would do this:
std::map<int,Foo*> myFoo;
extern "C" void myWindowRsize(int width, int height);
myInitGlut()
{
// Do Init stuff
glutReshapeFunc(&myWindowRsize);
}
myCreateWindow(std::string const& name)
{
// When a window is created store the mapping:
winID = glutCreateWindow(name.c_str());
// Now we have a new Foo for each window
// Note this code is not complete myFoo should manage the objects this suggests
// using a container of smart pointers or a smart container see boost for details.
myFoo[winID] = new Foo();
}
// Your static resize function called for all windows
void myWindowRsize(int width, int height)
{
// Get the current window. Then get the foo object for that windows.
int currentWindow = glutGetWindow();
Foo* windowsFoo = myFoo[currentWindow];
// Call your resize method.
windowsFoo->Resize(width, height);
}
Simply adding static to the function does the trick as Remus Rusanu states above. This ensures that the method is always available.
精彩评论