How to convert void (myClass::*)() to void (*)() - c++

I'm currently working on a C++ project on the Unreal Engine and I can't wrap my head around this problem.
class A
{
public:
void (* array[10])();
//Add Function to an array
void AddFunctionToArray(void(*function)());
};
class B
{
public:
A a;
//Sending a B function to A
void SendMyFunction();
void Foo();
};
void B::SendMyFunction()
{
a.AddFunctionToArray(&B::Foo);
}
I get the error: can't convert void (B::*)() to void (*)()
How can I send a function pointer from one of my class to another?

void (B::*)() is a pointer to a non-static member function, while void (*)() is a pointer to a non-member function. There is no conversion between the two.
Making B::Foo static would fix this problem. However, you will have no access to instance members of B.
Note that using function pointers, member or non-member, is an old style of passing function objects. A more modern way is using std::function objects, which can be constructed from a combination of an object and one of its member functions.

If you're looking to have class A execute a method from an arbitrary class X you can try this:
template <typename UserClass>
void A::FireMethod(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, void(int)>::Type InFunc)
{
(InUserObject->*InFunc)(15);
}
In this case we're calling a function with a single int as argument. A class B could do this:
A* a = myAObject;
a->FireMethod(this, &B::MyMethod);
with
void B::MyMethod(int) {}
Hope this helps you! If you want more information, in unreal engine you can look at the AddDynamic macro in Delegate.h

Related

Give another class access to specific methods

I am working on game engine as a project during the summer. Every scriptable component should have access to some methods in the scene which they are in. To make this possible i pass lambdas from the scene that calls the respective methods to the scriptable where they are implicitly converted to std::function types.
Scene.h:
class Scene
{
private:
unsigned int _currentId;
std::vector<System*> _systems;
//SCRIPTABLE NEEDS THE BELOW METHODS THESE EXCLUSIVELY:
bool exists(unsigned id);
void destroy(unsigned int);
void addComponent(Component*, unsigned int);
template<typename T> T& getComponent(unsigned int);
template<typename T> bool hasComponent(unsigned int);
template<typename T> void removeComponent(unsigned int);
protected:
unsigned int instantiate(std::vector<Component*>);
public:
Scene(ChangeSceneCallback);
~Scene();
void initiate();
void update(long dt);
};
template<typename T>
inline T & Scene::getComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return static_cast<T*>(system->getComponent(entityId));
}
}
}
template<typename T>
inline bool Scene::hasComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return system->contains(id);
}
}
}
template<typename T>
inline void Scene::removeComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return system->destroy(id);
}
}
}
The callback method works for the non-template functions i need access to, but not the templated ones, so it's out of the question.
Scriptable:
typedef std::function<void(int)> ChangeSceneCallback;
typedef std::function<int(std::vector<Component*>)> InstantiateCallback;
typedef std::function<void(int)> DestroyCallback;
typedef std::function<bool(int)> ExistCallback;
typedef std::function<void(Component*, unsigned int)> AddComponentCallback;
class Scriptable: public Component
{
protected:
ChangeSceneCallback changeScene;
InstantiateCallback instantiate;
DestroyCallback destroy;
ExistCallback exists;
public:
~Scriptable();
Scriptable();
void assignCallbacks(ChangeSceneCallback, InstantiateCallback etc ...);
virtual void init() = 0;
virtual void update() = 0;
};
Scriptable can't have access to public methods in scene because this would give the user / developer access to them (Scriptable is a base class for the behaviour of the game). That is why i need to come up with something that gives scriptable limited access to scene.
Any thoughts?
You cannot have a type erased "template callback". You have to choose between the template or the type erasure. Let me explain.
This is what a "template callback" look like. This is in fact a generic lambda:
auto print_callback = [](auto var) {
std::cout << var << std::endl;
}
print_callback(4) ; // prints "4"
print_callback(4.5); // prints "4.5"
print_callback("hello"); // prints "hello"
It seems good but notice that you can't do that with std::function, since you have to predefine the signature.
std::function<void(int)> func_print_callback = print_callback;
func_print_callback(5); // Yay! Prints "5"
func_print_callback("hello"); // error
The thing is, you might think the limitation is only because std::function need a specific signature to work with, but the limitation is much deeper than that.
The thing is, the is no template function. They don't exists. Function template on the other hand, do exist. Why I emphasize so much on the order of my words is because the name of this thing says it all: it is not a function, it a template that is used to make functions.
Here's a simple example:
template<typename T>
void foo(T t) {
std::cout << t << std::endl;
}
This function is not compiled. Because it's not a function. No function foo will exist until the hole T has been filled.
How do you fill the hole named T supposed to be a type?
By filling it with a type of course!
foo(5.4); // the hole T is `double`
When the compiler sees this, it knows you need a function named foo that takes a double as parameter. There is no function named foo that takes a double. But we gave the compiler a tool to create one: the template!
So the compiler will generate this function:
void foo_double(double t) {
std::cout << t std::endl;
}
The word here is this: generate. The compiler need to create the function in order to exist. The compiler generate code for you.
When the function is generated and compiled, T do not exist anymore. A template parameter is a compile-time entity, and only the compiler knows about them.
Now, I'll explain to you why there is no such thing as a template callback.
Type erased container such as std::function are implemented with pointer to function. I'll use type aliases to ease the syntax a bit. It works like this:
// A function
void foo(int) {}
// The type of the pointer to function
using func_ptr = void(*)(int);
// A pointer to foo
func_ptr ptr = &foo;
The pointer to the function foo has a value that points to the location of foo in the memory.
Now imagine we have a way to have template function pointer. We would have to point to a function that does not exist yet. It has no memory location, so it cannot make sense. And through the pointer, when invoked as a function, you'd have to generate the function code.
Since a pointer to function can point to any function, even functions that aren't known to the compiler yet, you'd have to somehow generate the function code and compile it. But the value of the pointer, to which function our pointer points to, is defined at runtime! So you'd have to compile code at runtime, for code that you don't know yet, from a value that does not exist, when the compiler don't exist anymore. As you can see, pointer to template function, template std::function or virtual template function cannot exist.
Now that you have understood the problem, let me propose a solution: drop the callback usage. You should call those functions directly.
You seem to use callback only to be able to call private member functions. This is the wrong way to do it, even if it works. What you need is friend, the feature of C++ that allows you to access private members.
class Scene {
friend Component;
// ...
};
class Component {
protected:
// Let `scene` be a reference to your scene
void addComponent(Component* c, unsigned int id) {
scene.addComponent(c, id);
}
template<typename T>
T& getComponent(unsigned int id) {
return scene.getComponent<T>(id);
}
template<typename T>
bool hasComponent(unsigned int id) {
return scene.hasComponent(id);
}
template<typename T>
void removeComponent(unsigned int id) {
removeComponent(id);
}
// ...
};
Since the Component class is the only friend to Scene, only it can call private member functions. Since all those newly defined functions in Component are protected, only class that extends from Component can call those. They are invoked like this:
class Scriptable : public Component {
void foo() {
hasComponent<Bar>(87); // works, call function defined in `Component`
}
};

Method of one class as callback from another

I will describe my problem the simplest as I can.
What is my issue:
I have frist class as a singleton:
class CTimer1
{
public:
static CTimer1 * getInstance(); //This gives me pointer to instance
void setChannelA(uint8_t compareValue);
private:
//Cnstructors
CTimer1(); //Prevent consttuction but allow in getInstance
CTimer1(const CTimer1&); //Prevent construction by copying
CTimer1& operator=(const CTimer1&); //Prevent assigment
~CTimer1(); //Prevent unwanted destruction
static CTimer1 * timerInstance;
static bool isCreated;
};
And here is second class where I would like to have possibility to call setChannelA method from CTimer1 class as a setPwm method from CServo class:
class CServo {
public:
CServo();
~CServo();
public:
//public methods
void registerPwmTimer(void (*callback)(uint8_t u8_buffer));
void (*setPwm)(uint8_t u8_buffer); //As this method I would like to call setChannelA from CTimer1 class
};
Here is registerPwmTimer method:
void CServo::registerPwmTimer(void (*callback)(uint8_t u8_buffer))
{
setPwm = callback;
}
Then I have tried to assign pointer to this method as a following:
int main()
{
CTimer1 * timer1 = CTimer1::getInstance();
CServo servo1();
servo1.registerPwmTimer(timer1->setChannelA);
servo1.setPwm(10); //This is example how I want to call setChannelA method
while(1)
{
}
}
I have error:
error: no matching function for call to 'CServo::registerPwmTimer(<unresolved overloaded function type>)'
What is important:
I can't use std::function because this is some part of code in C++ for embedded device, so I need to save memory consumption. Is there any way that I will be able to achieve this effect? If ony one possibility to do this is ot use some std library please for answers too. Thanks for your help.
Your problem is that a function pointer necessarily has to point to a static function. When you invoke an instance function (a method) there is a hidden first argument, which is the object on which the function was invoked. (This hidden argument is available as this within the function's definition.)
Your CServo::registerPwmTimer() function signature is simply incompatible with invocation of a member function; function pointers alone do not provide a way to bind an argument to the pointer, so even if you could convey the member function pointer using a (free) function pointer type, the hidden this argument could not be determined when the function pointer was invoked.
To put it another way, it would fail for the same reason that trying CTimer1::setChannelA(0) would fail -- you want to invoke that method, but you haven't communicated which object on which to invoke it.
Change the signature of CServo::registerPwmTimer to accept an std::function object instead of a raw function pointer. std::function objects can be constructed from function pointers, but they can also be constructed from lambdas, and some standard library functions return function objects:
void registerPwmTimer(std::function<void(uint8_t)>);
Now, you can use std::bind to create a new function that binds the object instance to the member function pointer:
servo1.registerPwmTimer(std::bind(&CTimer1::setChannelA, timer1));
Note that std::bind does not extend the lifetime of the object pointed to by timer1. If the returned function is invoked after that object is destructed, the result is undefined behavior.
Another alternative would be to accept both an instance and a pointer to a member function. The problem with this approach is it requires using templates:
template <typename T>
void registerPwmTimer(void (T::*)(uint8_t), T&);
This isn't bad in itself, but what you'll wind up doing is creating a polymorphic wrapper class so that you can insert this into your callback list alongside other callbacks that don't share the same T. At that point, you're just recreating std::function, since std::function already serves the purpose of being a polymorphic wrapper around callable things.
To illustrate the mess of implementing a polymorphic callable wrapper yourself, here is a very light example. I will show the declarations of a set of these types, and link to an example implementation.
This is the base type, with a pure virtual operator() that serves as the invocation operation.
class poly_callable
{
public:
virtual void operator()(int) const = 0;
};
Now we have a type for function pointers (also works with pointer-to-functor):
template <typename T>
class fn_poly_callable : public poly_callable
{
public:
typedef T fn_type;
fn_poly_callable(T);
virtual void operator()(int) const;
private:
T fn;
};
And one for member functions -- oh, but const member functions and non-const member functions are not interchangeable, so we need an extra template parameter for that:
template <typename T, typename M = void (T::*)(int)>
class member_poly_callable : public poly_callable
{
public:
typedef T object_type;
typedef M member_fn_type;
member_poly_callable(member_fn_type, object_type&);
virtual void operator()(int) const;
private:
member_fn_type mfn;
object_type& target;
};
Plus we'll want some helper functions to allow the compiler to infer the template types. One for function pointers:
template <typename T>
std::unique_ptr<poly_callable> make_poly_callable(T fn)
{
return std::unique_ptr<poly_callable>(new fn_poly_callable<T>(fn));
}
Two for member functions (const and non-const):
template <typename T>
std::unique_ptr<poly_callable> make_poly_callable(void (T::*mfn)(int), T& target)
{
return std::unique_ptr<poly_callable>(new member_poly_callable<T>(mfn, target));
}
template <typename T>
std::unique_ptr<poly_callable> make_poly_callable(void (T::*mfn)(int) const, T& target)
{
return std::unique_ptr<poly_callable>(new member_poly_callable<T, void (T::*)(int) const>(mfn, target));
}
If you want to see it all in action, I made a "simple" and working example.
So... just use std::function. There's no reason to reinvent this stuff.

Function pointer in class A to member function from class B

I'm searching a solution for this for a few days now. Didn't find any question related enough to answer regrettably so here is my question.
Consider the next code:
// dummy class A
class A {
public:
void aFunction() { // <- this is the function I want to point at
cout << "aFunction() is called\n";
}
};
class B {
public:
template <class Class> // get a function pointer
void setFunction( void (Class::*func)() ) {
p_func = func;
}
void (*p_func)(); // the function pointer
}
int main() {
B obj;
objb.setFunction(&A::aFunction);
return 0;
}
I have a compilation error in setFunction() on p_func = func;:
cannot convert from 'void (__thiscall A::* )(void)' to 'void (__cdecl *)(void)'
And I don't seem to be able to get rid of it in any way. I know it has something to do with those invisible this pointers (__thiscall and __cdecl), but I don't know how to handle these. I tried making the member variable p_func a class template too (void (Class::*p_func)()) so it would have the same structure, but it that seems to be illegal to have 2 class templates in one class (why?), thus isn't the correct solution. This time the compiler complains about:
multiple template parameter lists are not allowed
This method (without the template) works perfectly on global functions (which is the workaround I currently use) and I saw the use of it in a library (sfgui), so it should be perfectly possible.
To have some context over why I'd want this: I'm trying to create a button. This button should be able to call whatever function I'd like. For now, I'd like it to call the start() function of an animation class I'm making.
p.s.: I know this example is useless since I can't run p_func: the function isn't static. I still need to add an object pointer (setFunction( void (Class::*func)(), Class* )), but that does not seem to be a problem. And I know about typedef to make a function pointer more readable, but not with a class template.
EDIT
After some more research I think the answer I need not the answer to this question, but rather another one. For once, I noticed that multiple template <class Class> is in fact allowed. However, it is not allowed on member variables since the compiler can't possibly know which class he'll need to use which probably is the reason for the error
multiple template parameter lists are not allowed
which is an odd description. Thanks anyway for the help, you did gave me a better insight.
You cannot convert a pointer-to-member Class::*func to a normal function pointer. They are of different types.
You should turn this:
void (*p_func)(); // the function pointer
into this:
void (class::*p_func)(); // the function pointer
You could also use a std::function<void()> and use boost::bind to bind it.
std::function<void()> fun = boost::bind(class::member_fun, args);
EDIT
What about making your B class a template so you can do this:
#include<iostream>
class A {
public:
void aFunction() { // <- this is the function I want to point at
std::cout << "aFunction() is called\n";
}
};
template<class T>
class B {
public:
void setFunction( void (T::*func)() ) {
p_func = func;
}
void (T::*p_func)(); // the function pointer
void callfunc()
{
(t.*p_func)(); //call pointer to member
}
private:
T t;
};
int main() {
B<A> obj;
obj.setFunction(&A::aFunction);
return 0;
}
Live Example
I found the complete answer myself while searching for a way to save *objects of an unknown type without using templates or void pointers which has been answered here. The solution is a bit dodgy, because you'll have to create a dummy parent which allows for certain conversions.
The idea is that you create a Parent and every object that is allowed to be pointed to must inherit from it. This way you can create a pointer as Parent *obj which can hold multiple types of objects, but of course only classes that inherit from Parent.
The same applies for function pointers. If you define your pointer as void (Parent::*func)() as member variable. You can ask the user a template function pointer template <class Class> setFunction( void (Class::*f)() ), which can hold any pointer to any class. Now you need to cast the function pointer to the desired class, Parent: static_cast<void(Parent::*)()>(f). Mind that this only works when Class inherits from Parent. Otherwise you'll get a compilation error.
Minimal Working Example
#include <iostream>
using namespace std;
// dummy class Parent
class Parent {};
// class A
class A : public Parent { // Mind the inheritance!
public:
A(int n) : num(n) {}
void print() { // <- function we want to point to
cout << "Number: " << num << endl;
}
int num;
}
// class B, will hold the 2 pointers
class B {
public:
B() {}
template <class Class> // will save the function and object pointer
void setFunction( void (Class::*func)(), Class *obj) {
function = static_cast<void(Parent::*)()>(func);
object = obj;
}
void execFunction() { // executes the function on the object
(object->*function)();
}
void (Parent::*function)(); // the function pointer
Parent *object; // the object pointer
}
int main() {
A a(5);
B b;
b.setFunction(&A::print, &a);
b.execFunction();
return 0;
}
I don't really like this solution. A better solution would be that class B could have a function where it returns a bool when the function needs to be executed. This way you could simply place an if statement in the main-function that executes the desired function.
A a(5);
B b;
while (;;) {
if (b.aTest())
a.print();
}
Where B::aTest() is declared as
bool B::aTest();
Hope this helps anyone that comes across the same problem. So it is perfectly possible but pretty dodgy in my opinion, and I don't encourage people using the first method.

How to store a function in a member of class? (Using function as callback)

I want to store a function as a class member and call it inside the class? Pretty much like a callback function. My class draw a document but every document must drawn differently. So I want to assign a function (written outside of the class) into one of the members of the class and then call it when I want to draw the document.
This function mostly is responsible for transforming objects according to each specific document.
Here is my class:
class CDocument
{
public:
CDocument();
~CDocument();
void *TransFunc();
}
void Transform()
{
}
int main()
CDocument* Doc = new CDocument();
Doc->TransFunc = Transform();
}
I know that this is probably simple question, but I couldn't find the answer by googling or searching SO.
I think, this is what you might want. Please get back to me if you have questions.
class CDocument
{
public:
CDocument():myTransFunc(NULL){}
~CDocument();
typedef void (*TransFunc)(); // Defines a function pointer type pointing to a void function which doesn't take any parameter.
TransFunc myTransFunc; // Actually defines a member variable of this type.
void drawSomething()
{
if(myTransFunc)
(*myTransFunc)(); // Uses the member variable to call a supplied function.
}
};
void Transform()
{
}
int main()
{
CDocument* Doc = new CDocument();
Doc->myTransFunc = Transform; // Assigns the member function pointer to an actual function.
}
You need to use a Pointer to member function.
typedef void (CDocument::*TransFuncPtr)();
And then you can use TransFuncPtr as an type.
With your edit It seems like you just need a Pointer to a Free function.
Here is a small working sample.
#include<iostream>
#include<string>
typedef void (*TransFuncPtr)();
class Myclass
{
public:
TransFuncPtr m_funcPtr;
};
void doSomething(){std::cout<<"Callback Called";}
int main()
{
Myclass obj;
obj.m_funcPtr = &doSomething;
obj.m_funcPtr();
return 0;
}
The C declaration syntax, inherited by C++, is tricky.
Your declaration
void *TransFunc();
is actually the same as
void* TransFunc();
which declares a function returning a pointer, and not a pointer to a function.
To have the * bind to the declared name, and not to the type, you have to use an extra set of parenthesis
void (*TransFunc)();

Class member function as callback using boost::bind and boost::function

I'm working through setting up a member function as a callback for a C-library that I'm using. The C-library sets up callbacks like this:
typedef int (*functionPointer_t)(myType1_t*, myType2_t*, myType3_t*);
setCallback(param1, param2, functionPointer, param4)
I would like to use boost::bind (if possible) to pass in the function pointer. I would prefer that the function being pointed to was a member of the instantiated class, not a static member. E.g.
Class A {
public:
A();
protected:
int myCallback(myType1_t*, myType2_t*, myType3_t*); //aka functionPointer_t
}
Can this be done using boost::bind and boost::function? Per How can I pass a class member function as a callback? (the 3rd answer) it appears that I could declare the following (somewhere, or as a typedef):
boost::function<int (A*, myType1_t*, myType2_t*, myType3*> myCallbackFunction
And then somewhere in A (the ctor) call boost::bind on that type, and pass it into the C-library call.
Is this possible, or am I off base? Thanks much.
No. Functor types like boost::function don't convert to function pointers for use with C callback mechanisms.
However, most C callback mechanisms have some kind of token mechanism, so your callback function (which is static) has some kind of context information. You can use this to write a wrapper class which maps these tokens to functor objects, and passes execution along to the right one:
class CallbackManager {
public:
typedef boost::function<int (type1*, type2*, type3*)> callback;
static void setCallback(CallbackManager::callback cb)
{
void *token = ::setCallback(staticCallback);
callbacks[token] = callback_I;
}
static void staticCallback(void* token, type1* a, type2* b, type3* c)
{ return mcallbacks[token](a, b, c); }
private:
static std::map<void*, callback > callbacks;
};
do not use map, it gives runtime overhead and clutter up code with static map.
use reinterpret_cast instead.
for instance
// clib.h
typedef void (*CALLBACK_FUNC)(int code,void *param);
void set_callback( CALLBACK_FUNC, void * param );
// a.h
class A {
public:
A()
{
::set_callback( &A::static_callback, this);
}
private:
static void static_callback(int code, void * param)
{
A* self = reinterpret_cast<A*>(param);
self->callback( code );
}
inline void callback( int code )
{
// write you code here.
}
};
The problem with member functions is that they automatically receive a pointer to object instance as the first parameter - "this" pointer. That's why you can't use member functions a C callback functions. You must have the object AND the function pointer together in order to use a member function.