Reputation: 178
I've recently decided to start working with callback functions to make my life a bit easier. However, I'm having a bit of an issue:
#include <iostream>
#include <functional>
#include <memory>
class setCallback
{
public:
setCallback() {}
setCallback(std::function<int()> func) : callback(func) { }
int call() { return callback(); }
private:
std::function<int()> callback;
};
class callThis
{
public:
callThis() : number(10) {}
static int another()
{
return number;
}
int number;
};
int main(int argc, char** argv[])
{
std::shared_ptr<setCallback> caller;
std::shared_ptr<callThis> funcholder;
funcholder.reset(new callThis);
caller.reset(new setCallback(funcholder->another));
std::cout << caller->call() << "\n";
std::cin.get();
}
As you can see from the code, I pull in the function from "callthis" into "setCallBack". This allows me to keep the function for later use, if needed. This works perfectly, however, if I attempt to load in a member variable from "callthis" into the static function, it obviously would not work (using a value does).
Is there a way around this? I would like to access the variable found within the class using the static function; optionally avoid using static functions when passing into the callback (but I assume this isn't possible due to the way callbacks work).
I've heard about wrapper classes but I'm not entirely sure how I would go about implementing it. Some insight would be appreciated.
Thanks a lot.
Edit:
Solved calling variables with callback functions, by B Sahu
Solved calling functions using callbacks without making the function being called static and keeping things reasonably uncoupled
I researched how to call non-static functions using C++11; I thought it might be useful if anyone ends up having the same issues I do. This works on the same principles as R Sahu proposed, however, using types and procedures found in it ends up being a bit cleaner. Using std::bind(class::func, object) you can effectively gain the same results.
int main(int argc, char** argv)
{
std::function<void(void)> somefunc;
Functionholder func;
somefunc = std::bind(&Functionholder::say, &func);
}
Credit for this goes to: This beautiful person
Which when used in a more complex example, having a class which holds the function to call, a caller class which will take the function and call it when required and a binder/state class (note, i'm using this for game UI), you can really get some reasonably neat and uncoupled code going:
#include <iostream>
#include <functional>
class Functionholder
{
public:
void say() { std::cout << "hello!\n"; }
};
class CallbackHandler
{
public:
CallbackHandler(){}
CallbackHandler(std::function<void()> call) { callback = call; }
void update()
{
//something happens to call this
callback();
}
std::function<void()> callback;
};
class TheState
{
public:
TheState()
{
hand = CallbackHandler(std::bind(&Functionholder::say, &func));
}
void update() { hand.update(); }
Functionholder func;
CallbackHandler hand;
};
int main(int argc, char** argv)
{
TheState state;
state.update();
std::function<void(void)> somefunc;
std::cin.get();
}
If you have any improvements let me know!
Upvotes: 0
Views: 4995
Reputation: 206587
Provide the ability to call the callback functions with user specified data. Then, use the data in the callback function.
#include <iostream>
#include <functional>
#include <memory>
class setCallback
{
public:
setCallback() {}
setCallback(std::function<int(void*)> func) : callback(func) { }
int call(void* data) { return callback(data); }
private:
std::function<int(void*)> callback;
};
class callThis
{
public:
callThis() : number(10) {}
static int another(void* data)
{
callThis* ptr = static_cast<callThis*>(data);
return ptr->number;
}
int number;
};
// Fixed this line. You had
// int main(int argc, char** argv[])
int main(int argc, char** argv)
{
std::shared_ptr<setCallback> caller;
std::shared_ptr<callThis> funcholder;
funcholder.reset(new callThis);
caller.reset(new setCallback(callThis::another));
std::cout << caller->call(funcholder.get()) << "\n";
std::cin.get();
}
Upvotes: 1