Is it possible to access the arguments from an std::bind object? - c++

Please consider the following scenario.
A hypothetical pop-up menu class that displays some actions, and when one of them is selected it will call the passed in action which is in form of an std::function:
PopupMenu::PopupMenu(std::function<void(RowItem*)> editRowFunction, RowItem *item)
: _editRowFunction(editRowFunction)
, _item(item) {
}
Then at some point it might call execute:
PopupMenu::execute(} {
_editRowFunction(_item);
}
Then I have this other class that's a UI object:
class EditorWidget {
void editRow(RowItem *row) {
//edit the row
}
}
And here's how I am using all of them:
int main() {
auto item = new RowItem();
auto editorWidget = new EditorWidget();
PopupMenu menu(std::bind(&EditorWidget::editRow, editorWidget, item), item);
menu.execute();
return 0;
}
Everything works. My question is the following:
If I am already passing the argument item in std::bind, why do I have to pass it again as a second parameter in order to be able to call the bound function with that argument? If I don't, and try to call the function just by itself from PopupMenu::execute(), I get a compiler error.
The other way around it is to make the constructor of PopupMenu like this:
PopupMenu::PopupMenu(std::function<void()> editRowFunction)
: _editRowFunction(editRowFunction) {}
And if I do it that way then I call it this way:
PopupMenu::execute() {
_editRowFunction();
}
What I don't like about this method is that I can pretty much pass any bound function in the PopupMenu constructor and it will be called. But that's not what I want, I want to enforce only a function with a specific signature.
I can also pass a lambda, yes. But let's try to solve it without lambdas.
Thank you all in advance for your help.

std::bind(&EditorWidget::editRow, editorWidget, item)
std::bind here is creating a functional object that takes a pointer to a member function EditorWidget::editRow, bound to an object editorWidget, using the parameter item. What you've done is actually fix the parameter to the function EditorWidget::editRow with the parameter item. So effectively you've created a function object that takes no argument (since you've fixed it), and returns void.
There's actually no need for the constructor of PopupMenu to have a second parameter of type RowItem*. You could change the constructor like so:
PopupMenu::PopupMenu(std::function<void()> editRowFunction)
: _editRowFunction(editRowFunction)
{
}
and then call your function object like this:
PopupMenu::execute(} {
_editRowFunction();
}
In your current code the parameter _item is not being used by the function object you pass into the constructor PopupMenu. It satisfies the compiler since _editRowFunction is of type std::function<void(RowItem*)>.
Here's a simple example to illustrate to the point:
#include <iostream>
#include <functional>
struct callable
{
callable(std::function<void(std::string)> fn) : mFn(fn)
{}
std::function<void(std::string)> mFn;
void Run() { mFn("world"); }
};
struct Foo {
void print(std::string msg)
{
std::cout << msg << '\n';
}
};
int main()
{
Foo f;
auto fn = std::bind(&Foo::print, &f, "hello");
fn();
callable c(fn);
c.Run(); //expecting "world" to be printed
}
You might expect the output to be:
hello
world
but actually it's:
hello
hello
Live demo.
What I could do is change the definition of the function object like this:
auto fn = std::bind(&Foo::print, &f, std::placeholders::_1); //uses a placeholder
and I get the expected output. You could do something similar without having to make many changes to your current implementation.

Related

How to create a pointer to a function pointer?

I'm trying to create a struct that have 2 function, which may be rewritten if needed later. The functions are: onClicked() and onClickedRight(). The code for the struct:
typedef struct {
QString text;
QString infoText;
QUrl iconSrc;
QColor iconColor;
void (*onClicked)() = nullptr;
void (*(*onClickedRight))() = &onClicked; // by default, execute the same function from onClicked()
} ConfigButton;
How I'm trying to execute these functions:
ConfigButton b;
...
// test if click funtion has been defined, to execute it
if (b.onClicked)
b.onClicked(); // this one work just fine
...
if (*(b.onClickedRight))
(*(b.onClickedRight))(); // this one crashed
Is it even possible? Am I missing something?
When onClicked is a function, both &onClicked and onClicked evaluate to the same thing -- a pointer to the function.
If you want to create a pointer to a function pointer, you need a pointer to a function as a variable first.
However, given your usage, you need just a pointer to a function.
typedef struct {
QString text;
QString infoText;
QUrl iconSrc;
QColor iconColor;
void (*onClicked)() = nullptr;
void (*onClickedRight)() = onClicked;
} ConfigButton;
and
if ( b.onClickedRight)
b.onClickedRight();
I think you can still solve your issue with a pointer to a function pointer, yet it is a bit clumsy, since you have to call this pointer-pointer in a different manner than you do with a "normal" function pointer. The call would look like (*(aButton.onRightClick))(), and you need to let onRightClick point to a pointer object pointing to a function rather than assigning the function directly.
I suppose you are looking for a way to define that onRightClick shall by default "inherit" the behaviour of onClick, unless the user overrides this and assigns a different behaviour to onRightClick. I see two requirements that a possible solution shall fulfill:
1) If onRightClick did not get overridden, it shall inherit every change made to onClick
2) If onRightClick gets overridden, it gets decoupled from onClick.
You can solve this with "simple" function pointers by assigning onRightClick a function that simply calls the one assigned to onClick. The following code shows this for C++; the approach can be transferred to C (though you then need to pass the "this" to the function calling onClick:
void defaultOnClick() {
std::cout << "defaultOnClick" << std::endl;
}
void otherClick() {
std::cout << "otherClick" << std::endl;
}
void rightClick() {
std::cout << "rightClick" << std::endl;
}
typedef std::function<void(void)> onClickFunctionType;
struct ConfigButton {
onClickFunctionType onClick = defaultOnClick;
onClickFunctionType onRightClick = [this](){ this->onClick(); };
} ;
int main() {
ConfigButton configButton;
std::cout << "default for both onClick and onRightClick (calling onClick)" << std::endl;
configButton.onClick();
configButton.onRightClick();
std::cout << "special click for onClick; 'inherited' by onRightClick" << std::endl;
configButton.onClick = otherClick;
configButton.onClick();
configButton.onRightClick();
std::cout << "special click for onClick; different one for onRightClick" << std::endl;
configButton.onRightClick = rightClick;
configButton.onClick();
configButton.onRightClick();
}
Output:
default for both onClick and onRightClick (calling onClick)
defaultOnClick
defaultOnClick
special click for onClick; 'inherited' by onRightClick
otherClick
otherClick
special click for onClick; different one for onRightClick
otherClick
rightClick
Answer adjusted, since OP has removed c from the tag list.
The code works as is. So you are doing something else wrong.
However, using a pointer to a pointer to a function in this way may not have the semantics that you want. If the structure gets copied to another structure, the onClickedRight member in the copy is not pointing to the onClicked pointer in its own instance. It is instead pointing to the onClicked pointer of the original instance.
a.onClickedRight = &a.onClicked;
b = a;
assert(b.onClickedRight == &a.onClicked); // Is this intentional?
What this means is that you have to be extra careful about how you use structures that contain pointers to its own members (and pointers to anything, really). You will probably need some kind of deep copy method (so, according to TRoT, you need a copy constructor, an assignment operator, and a destructor).
In any case, the C++ code is not really idiomatic. For myself, I would probably leverage virtual methods. The virtual method syntax can easily accommodate this use case.
struct ConfigButton {
QString text;
QString infoText;
QUrl iconSrc;
QColor iconColor;
virtual void onClicked() const = 0;
virtual void onClickedRight () const { onClicked(); }
};
struct Foo : ConfigButton {
void onClicked () const {
//...
}
};
If you follow this method, this will also work.
One possible approach is to have functions that implement the logic of firing the handler. You already have some logic (if (onClicked)) that the caller has to do anyway, so this minimizes the possibility of the caller making a mistake .
struct ConfigButton {
// ...
void Fire_OnClicked()
{
if ( onClicked )
onClicked();
}
void Fire_OnClickedRight()
{
if ( onClickedRight )
onClickedRight();
else
Fire_OnClicked();
}
private:
void (*onClicked)() = nullptr;
void (*onClickedRight)() = nullptr;
};
You could combine this with the std::function version, testing for empty instead of requiring "empty" to be represented by a lambda performing the default action. And if there are multiple handlers you want to have default fallback you could reduce boilerplate by making a template Fire function.
Another approach that might work would be to make a custom handler type with similar semantics to std::function but its () operator will perform a default action if no function has been set .
In the C language functions pointers are the only place where hiding pointers behind typedefs makes sense
https://godbolt.org/z/Gb_WEy
#include <stdio.h>
typedef int (*fptr_t)();
typedef struct
{
fptr_t fptr;
fptr_t *pfptr;
fptr_t **ppfptr;
fptr_t ***pppfptr;
}MYSTRUCT_t;
int foo(char *caller)
{
printf("Function name = %s, caller = %s\n", __FUNCTION__, caller);
return 0;
}
int main()
{
MYSTRUCT_t mystr;
mystr.fptr = foo;
mystr.pfptr = &mystr.fptr;
mystr.ppfptr = &mystr.pfptr;
mystr.pppfptr = &mystr.ppfptr;
printf("mystr.fptr=%p mystr.pfptr=%p func=%p\n", (void *)mystr.fptr, (void *)mystr.pfptr, (void *)&foo);
foo("foo");
mystr.fptr("mystr.fptr");
(*mystr.pfptr)("mystr.pfptr");
(*(*mystr.ppfptr))("mystr.ppfptr");
(*(*(*mystr.pppfptr)))("mystr.pppfptr");
}

Can you help me to understand why this bind works?

I'm trying to understand bind and pre-fill functions in C++.
Here's my example:
#include <iostream>
#include <functional>
#include <vector>
class Voice
{
public:
double mValue;
private:
};
class VoiceManager
{
public:
VoiceManager() { }
~VoiceManager() { }
typedef std::function<void(Voice &)> VoiceChangerFunction;
inline void UpdateVoices(VoiceChangerFunction callback) {
for (int i = 0; i < mNumOfVoices; i++) {
callback(mVoices[i]);
}
}
static void SetValue(Voice &voice, unsigned int value) {
voice.mValue = value;
std::cout << voice.mValue << std::endl;
}
private:
static const int mNumOfVoices = 4;
Voice mVoices[mNumOfVoices];
};
int main()
{
VoiceManager voiceManager;
VoiceManager::VoiceChangerFunction callback;
callback = std::bind(&VoiceManager::SetValue, std::placeholders::_1, 100);
voiceManager.UpdateVoices(callback);
}
Basically, I create a VoiceChangerFunction function (object) that takes a Voice & as first parameter and returns void.
Later, I bind a function that will take as first parameter the one I'll give to it when I call it, and another parameter that I give when I bind it (100, in my example).
Right?
What I don't understand is: then, this function is passed to UpdateVoices(), which take as input a function/object that has 1 param (Voice &), not 2 as created in my bind function (Voice &, unsigned int).
How can it works?
Its like to have void VoiceChangerFunction(Voice &voice) and call VoiceChangerFunction(Voice &voice, unsigned int value ).
The function prototype is different. I mean: the callback bind I created isn't a VoiceChangerFunctions function, because it takes more parameters.
How can it works/match?
That is exactly the beauty of bind and std::function at works. You are defining the callback as function taking one argument, and bind is returning a function object which takes one argument.
The main point here is that it actually calls the function which takes 2 parameters, but the second one is fixed, and will always be 100 (in your case). This is the sole purpose of binders - to provide a way to call functions with different set of arguments with some fixed values. If you would be calling the function taking the same set of arguments, there would be no reason to use binders at all!
Knowing that bind is similar to lambdas, the same code could be written as - and probably be more clear:
VoiceManager::VoiceChangerFunction callback;
callback = [](Voice& v) { VoiceManager::SetValue(v, 100); };
voiceManager.UpdateVoices(callback);
And if you are curious how it works, you might try to create a binder framework yourself. If you are only doing it for educational purposes and not worried about too many details, it is not that hard.
When you bind, you're making a new function that only takes Voice as a param, that's why it works.
void a_func(int x) { return; }
std::function<void(void)> new_func = std::bind(&a_func, 1);
new_func now has the signature of void(void), so you could pass it around to anywhere that expects a function of type void(void).
When you call new_func, it really calls a_func(1).
Your assumption about bind is wrong.
Your bind call returns a function object that will accept one parameter, namely the placeholder. The other parameter on your function is already bound to 100.
A little example:
void foo(int i1, int i2) {};
std::function<void(int,int)> fn1 = std::bind(foo, std::placeholders::_1, std::placeholders::_2);
std::function<void(int)> fn1 = std::bind(foo, std::placeholders::_1, 1);
std::function<void()> fn1 = std::bind(foo, 1, 1);
The bind will create a matching function depending on bound and unbound parameters.
Update
The compiler will generate a struct from the bind expression and a copy of your parameter. Simplified something like this(this will not compile):
struct Function_{
void(*fn)(Voice &, unsigned int)
unsigned int i_;
Function_(void(*f)(Voice &, unsigned int), unsigned int i):fn(f),i_(i){}
void operator()(Voice& v){
fn(v, i_);
}
}
fn is the first parameter which is a function pointer and the bound (100) is the second. Then all you need is some type erasure and your own bind is ready to go.

c++ save class templated function pointer inside map

I'm having a small problem which I can't wrap my head around.
I have a function that looks like this:
template <typename T>
std::unique_ptr<Environment>& CreateEnvironment(sf::Vector2f& _position, bool _addToStatic = false);
This is my function pointer typedef
typedef std::unique_ptr<Environment>& (WorldEditor::*CreateEnvironmentPtr)(sf::Vector2f&, bool);
std::map<std::string,CreateEnvironmentPtr> listEnv;
And I'm trying to simply do this:
listEnv["test"] = &CreateEnvironment<Coin>(sf::Vector2f(200,200), false);
And i get the following error:
error C2440: '=' : cannot convert from 'std::unique_ptr<_Ty> *' to
'std::unique_ptr<_Ty> &(__thiscall WorldEditor::* )(sf::Vector2f
&,bool)'
I understand what the error is saying, but I don't know how to solve it. Also why does it even care about the return type when I'm pointing to the address of the function?
Best regards
nilo
problems such as these are often much better solved with std::function
std::map<std::string, std::function<void()> listEnv;
listEnv.emplace("test", [] {
CreateEnvironment<Coin>(sf::Vector2f(200,200), false);
});
to call:
listEnv.at("test")->second();
Based on your post I am not sure if you are attempting to create the member function pointer and map inside the CreateEnvironment class or outside of it, so I'll solve what I think is the more difficult problem of pointer to a separate object's member function.
I simplified your classes like so:
Environment
struct Environment
{
int i = 1;
};
Coin
struct Coin
{
int k = 0;
};
WorldEditor
struct WorldEditor
{
template <typename T>
std::unique_ptr<Environment> CreateEnvironment(int& _j, bool _addToStatic = false)
{
return std::make_unique<Environment>();
}
};
Solution: Map an object's member fn pointer, and then call it later
(I will be using C++11/14 syntax in my answer)
//declare a pointer to member function in WorldEditor
using CreateEnvironmentPtr = std::unique_ptr<Environment> (WorldEditor::*)(int&, bool);
//declare an object of type WorldEditor, because member function pointers need a "this" pointer
WorldEditor myWorldEditor;
int myInt = 42;
//map a string to the CreateEnvironment<Coin> function
std::map<std::string, CreateEnvironmentPtr> listEnv;
listEnv["test"] = &WorldEditor::CreateEnvironment<Coin>;
// call the member function pointer using the instance I created, as well as
// the mapped function
(myWorldEditor.*listEnv["test"])(myInt, false);
// (printing member value to cout to show it worked)
std::cout << (myWorldEditor.*listEnv["test"])(myInt, false)->i << std::endl; // prints 1
Live Demo
Solution 2: use std::bind and std::function
Perhaps we already know the parameters to the member function call at the time we create the entry for map. Using std::bind with a std::function will help us achieve that (Similar to Richard Hodges' solution):
// now our "function pointer" is really just a std::function that takes no arguments
using CreateEnvironmentPtr = std::function<std::unique_ptr<Environment>(void)>;
//declare an object of type WorldEditor, because member function pointers need a "this" pointer
WorldEditor myWorldEditor;
int myInt = 42;
//map a string to that function pointer
//ensure it gets called with the right args
// by using std::bind (which will also make the arg list appear the be void at call time)
// note that std::bind needs an instance of the class immediately after
// listing the function it should be binding
// only afterwards will we then pass the int& and bool
std::map<std::string, CreateEnvironmentPtr> listEnv;
listEnv["test"] = std::bind(&WorldEditor::CreateEnvironment<Coin>, &myWorldEditor, myInt, false);
// the mapped function
listEnv["test"]()->i;
// (printing resulting unique_ptr<Environment>'s member to cout to show it worked)
std::cout << listEnv["test"]()->i << std::endl; // prints 1
Live Demo 2

Calling the function pointed by a Pointer-to-Member-Function from within a struct

I have a class Test with a peculiar data structure.
A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, pmf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance,
Jir
The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();

Callback to non-static method

Think of your basic GLUT programs. They simply run from a main method and contain callbacks like `glutMouseFunc(MouseButton) where MouseButton is the name of a method.
What I have done is I have encapsulated the main file into a class, so that MouseButton is no longer a static function but has an instance. But doing this gives me a compilation error :
Error 2 error C3867: 'StartHand::MouseButton': function call missing argument list; use '&StartHand::MouseButton' to create a pointer to member c:\users\angeleyes\documents\visual studio 2008\projects\capstone ver 4\starthand.cpp 388 IK Engine
It is not possible to provide a code sample as the class is quite huge.
I have tried using this->MouseButton but that gives the same error. Can't a pointer to an instance function be given for callback?
As the error message says, you must use &StartHand::MouseButton syntax to get a pointer to a member function (ptmf); this is simply mandated as part of the language.
When using a ptmf, the function you are calling, glutMouseFunc in this case, must also expect to get a ptmf as a callback, otherwise using your non-static MouseButton won't work. Instead, a common technique is for callbacks to work with a user-supplied void* context, which can be the instance pointer—but the library doing the callbacks must explicitly allow this parameter. It's also important to make sure you match the ABI expected by the external library (the handle_mouse function below).
Since glut doesn't allow user-supplied context, you have to use another mechanism: associate your objects with glut's current window. It does provide a way to get the "current window", however, and I've used this to associate a void* with the window. Then you simply need to create a trampoline to do the type conversion and call the method.
Machinery:
#include <map>
int glutGetWindow() { return 0; } // make this example compile and run ##E##
typedef std::pair<void*, void (*)(void*,int,int,int,int)> MouseCallback;
typedef std::map<int, MouseCallback> MouseCallbacks;
MouseCallbacks mouse_callbacks;
extern "C" void handle_mouse(int button, int state, int x, int y) {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) { // should always be true, but possibly not
// if deregistering and events arrive
i->second.second(i->second.first, button, state, x, y);
}
}
void set_mousefunc(
MouseCallback::first_type obj,
MouseCallback::second_type f
) {
assert(obj); // preconditions
assert(f);
mouse_callbacks[glutGetWindow()] = MouseCallback(obj, f);
//glutMouseFunc(handle_mouse); // uncomment in non-example ##E##
handle_mouse(0, 0, 0, 0); // pretend it's triggered immediately ##E##
}
void unset_mousefunc() {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) {
mouse_callbacks.erase(i);
//glutMouseFunc(0); // uncomment in non-example ##E##
}
}
Example:
#include <iostream>
struct Example {
void MouseButton(int button, int state, int x, int y) {
std::cout << "callback\n";
}
static void MouseButtonCallback(
void* self, int button, int state, int x, int y
) {
static_cast<Example*>(self)->MouseButton(button, state, x, y);
}
};
int main() {
Example obj;
set_mousefunc(&obj, &Example::MouseButtonCallback);
return 0;
}
Notice that you don't call glutMouseFunc directly anymore; it is managed as part of [un]set_mousefunc.
Just in case it isn't clear: I've rewritten this answer so it should work for you and so that it avoids the C/C++ linkage issue being debated. It will compile and run as-is (without glut), and it should work with glut with only minor modification: comment or uncomment the 4 lines marked ##E##.
No, a pointer to an instance function can not be given to a callback function expecting a function pointer of a certain signature. Their signatures are different. It won't compile.
Generally such APIs allow you to pass in a void* as a "context" parameter. You pass in your object there, and write a wrapper function which takes the context as the callback. The wrapper casts it back to whatever class you were using, and calls the appropriate member function.
You can't replace a static callback with an instance one. When the caller calls your callback, on what instance whoul it call? In other words, how does the caller pass in the formal 'this' argument?
The solution is to have a static callback stub and pass the instance as argument, which implies the callee must accept an arbitrary pvoid that will pass back when invoking the callback. In the stub, you can then call the non-static method:
class C {
void f() {...}
static void F(void* p) {
C* pC = (C*)p;
pC->f();
}
}
C* pC = ...;
someComponent.setCallback(&C::F, pC);
Contrary to what everyone seems to be saying, you most definitely CAN use a non-static member function as a callback method. It requires special syntax designed specifically for getting pointers to non-static members, and special syntax to call that function on a specific instance of a class. See here for a discussion of the needed syntax.
Here is sample code that illustrates how this works:
#include <cstdlib>
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
class Operational
{
public:
Operational(int value) : value_(value) {};
string FormatValue() const ;
private:
int value_;
};
string Operational::FormatValue() const
{
stringstream ss;
ss << "My value is " << value_;
return ss.str();
}
typedef string(Operational::*FormatFn)() const; // note the funky syntax
Operational make_oper(int val)
{
return Operational(val);
}
int main()
{
// build the list of objects with the instance callbacks we want to call
Operational ops[] = {1, 2, 3, 5, 8, 13};
size_t numOps = sizeof(ops)/sizeof(ops[0]);
// now call the instance callbacks
for( size_t i = 0; i < numOps; ++i )
{
// get the function pointer
FormatFn fn = &Operational::FormatValue;
// get a pointer to the instance
Operational* op = &ops[i];
// call the callback on the instance
string retval = (op->*fn)();
// display the output
cout << "The object # " << hex << (void*)op << " said: '" << retval << "'" << endl;
}
return 0;
}
The output of this program when I ran it on my machine was:
The object # 0017F938 said: 'My value is 1'
The object # 0017F93C said: 'My value is 2'
The object # 0017F940 said: 'My value is 3'
The object # 0017F944 said: 'My value is 5'
The object # 0017F948 said: 'My value is 8'
The object # 0017F94C said: 'My value is 13'
You cannot use a non-static member function in this case.
Basically the type of the argument expected by glutMouseFunc is
void (*)(int, int, int, int)
while the type of your non-static member function is
void (StartHand::*)(int, int, int, int)
First problem is that types don't really match.
Second, in order to be able to call that method, the callback would have to know which object ( i.e. "this" pointer ) your method belongs to ( that's pretty much why the types are different in the first place ).
And third, I think you're using the wrong syntax to retrieve the method's pointer. The right syntax should be: &StartHand::MouseButton.
So, you have to either make that method static or use some other static method that would know which StartHand pointer to use to call MouseButton.
The following works in c++ to define a c callback function, useful for example when using glut (glutDisplayFunc, glutKeyboardFunc, glutMouseFunc ...) when you only need a single instance of this class :
MyClass * ptr_global_instance = NULL;
extern "C" void mouse_buttons_callback(int button, int state, int x, int y) {
// c function call which calls your c++ class method
ptr_global_instance->mouse_buttons_cb(button, state, x, y);
}
void MyClass::mouse_buttons_cb(int button, int state, int x, int y) {
// this is actual body of callback - ie. if (button == GLUT_LEFT_BUTTON) ...
// implemented as a c++ method
}
void MyClass::setup_glut(int argc, char** argv) { // largely boilerplate glut setup
glutInit(&argc, argv);
// ... the usual suspects go here like glutInitWindowSize(900, 800); ...
setupMouseButtonCallback(); // <-- custom linkage of c++ to cb
// ... other glut setup calls here
}
void MyClass::setupMouseButtonCallback() {
// c++ method which registers c function callback
::ptr_global_instance = this;
::glutMouseFunc(::mouse_buttons_callback);
}
In your MyClass header we add :
void mouse_buttons_cb(int button, int state, int x, int y);
void setupMouseButtonCallback();
This also works using identical logic flows to setup your glut
call to glutDisplayFunc(display)