Function pointer in class A to member function from class B - c++

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.

Related

Functional template programming instead of inheritance

I'm currently working on a piece of code in C++11:
class A {
public:
//.. generic public methods which call updateInternalState from time to time ..
private:
void updateInternalState();
B internalState;
};
Now I want to have several versions of class A which are all identical except for the updateInternalState() method, which is to vary and has atleast 3 different versions, doing different things and might have even more in the future. This sounds almost like a good place to use inheritance with a base class, but I'm wondering if there is a template-metaprogramming version for this, e.g.:
#include <functional>
template <std::function<void()> updateInternalState>
class A {
public:
//.. generic public methods, which call updateInternalState from time to time ..
private:
B internalState;
Then I would only have to define the functions somewhere else and explicitly instantiate the versions of A that I want.
I think the biggest problem is that the updateInternalState function needs access to the private members of A. I'm thinking this could be solved by declaring it as a friend of A, or by storing a member of type std::function and assigning the the template argument to it.
Does anyone have experience with such approaches and any recommendations?
Is it a terrible idea and should I just go back to inheritance (which I do not really want, since the rest of the project is written in the generic programming paradigm.)
If update function only uses internalState, you can simply store std::function<void(B&)> as a member, which is passed during construction:
class A
{
public:
template <typename F>
A(F&& func)
: updateFunc(std::forward<F>(func))
void doSomething()
{
updateFunc(internalState);
}
private:
using UpdateFunc = std::function<void(B&)>;
B internalState;
UpdateFunc updateFunc;
};
With this method, you can achieve nice flexibility while still maintaining single type instead of whole hierarchy.
Template-based solution may not be a good idea here - you only need to customize a single function, but making this a class template will cause to generate the whole class for every different function used as an argument. The only advantage is that you can specialize (or partially specialize) the logic, but it sounds like you doesn't need that.
Use inheritance or store update function as a member.
That will be a full academic answer :-)
First remark: What you want to do simply makes no sense!
Step by step:
You can use function pointers as template parameters as this:
using FUNCPTR_T = void(*)();
template < FUNCPTR_T f >
class A {
public:
void DoSomething()
{
(*f)();
}
};
void f1() { std::cout << "f1" << std::endl; }
void f2() { std::cout << "f2" << std::endl; }
int main()
{
A<f1> a1;
A<f2> a2;
a1.DoSomething();
a2.DoSomething();
}
But if you want to pass a parameter to your function, which is a class pointer ( this ), you need to define a function pointer which represents this like:
using FUNCPTR_T = void(*)(!!!POINTER_TO_THE_CLASS!!!);
But this class itself is a template which takes a pointer to a function which has a parameter which is a pointer to a class which takes a pointer to a function .... // endless recursion!
So your attempt simply fail at the point as you are unable to give a correct type for the template parameter.
And as already mentioned: Inheritance is much easier and works perfect. Using CRTP is often used to get access to the using class. Using std::function is much easier but moves the cost to runtime.
You can store a std::function and use lambdas: check out this simple class and its use as an example:
#include <functional>
#include <iostream>
#include <conio.h> // for _getch()
class A {
private:
int _state;
std::function<int()> _updater;
public:
A() : _state( 0 ) {}
void addUpdater( std::function<int()> updater ) {
_updater = updater;
}
void callUpdater() {
updateInternalState();
}
int returnState() const {
return _state;
}
private:
void updateInternalState() {
_state = _updater();
}
};
int main() {
A a;
a.addUpdater( []() { return 5; } );
a.callUpdater();
std::cout << a.returnState() << std::endl;
a.addUpdater( []() { return 10; } );
a.callUpdater();
std::cout << a.returnState() << std::endl;
_getch();
return 0;
}
Then to keep track of different instances of the same class, instead of inheritance you can use a map <id, this*> where id could be an int or a string. Makes for easy look up too. I think this might be better than templates in this situation because if you template this class where only the function differs it will generate a whole new class for each function change. Yes it does move things to runtime because of std::function, but it appears to be simpler to implement and manage.

How to convert void (myClass::*)() to void (*)()

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

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`
}
};

Storing multiple types into the same container [duplicate]

This question already has answers here:
Heterogeneous containers in C++
(7 answers)
Closed 8 years ago.
Introduction
Say I have the follow
class thing {
template<typename T> void method(T value) {}
}
What I want to do is to store whatever value is passed into value no matter what type into a std::vector or something and without turning this into a template class (because that doesn't solve my problem in anyway)
I want to be able to do this without using boost (as much i love boost i am not going to use it all the time)
Attempted Ideas
Void Pointer
My initial though is to use a void* however i would lose the type of the object and it could end up being unsafe.
Union/Struct
My next thought was to use a union/struct like the one below:
union type_wrapper {
int a;
char f;
/* etc, etc, etc */
}
However i would run into the same problem as I would have to track the type, so i make sure it remains the same when ever used.
Wrapper Class
Then next thing i attempted was a class that would return the type in a function call like so:
template<typename T>
class type_wrapper {
T getType() { return /* get value of type/pointer/object here */ }
/*Stored in some manner */
}
Problem with is the same thing as with just the type on its own in that it cannot be stored in a list called lets say std::list<AClass> when its of type std::list<BClass> or std::list<int> etc
Other thing
All other examples i have looked at have do what i am doing but are expect that you track the type of the object one way or another, or use boost.
tl;dr
What could i try doing so that i could pass a parameter of type int and storing into a std::list etc it while using the same template function to pass a parameter of type 'cheese' (an imaginary class dedicated to filling your programs with cheese) and storing it into the same list, etc
I don't know if this will solve your problem, but you can use some polymorphic type for the container, and encapsulate the object in a generic derived class, so calls to object's member functions from the derived class' member functions can have full type information (they will be specialized templates), but your "thing" won't be generic, and client code won't care (or even know) about this inhertance:
class Aux {
public:
virtual void DoSomething() =0 ;
};
template<typename T>
class AuxTemp : public Aux {
T *real_obj;
public:
AuxTemp(const T &obj) : real_obj(new T(obj)) {} // create
AuxTemp(const AuxTemp &other) : real_obj(new T(*other.real_obj)) { } // copy
AuxTemp(AuxTemp &&other) : real_obj(other.real_obj) { other.real_obj=nullptr; } // move
~AuxTemp() { delete real_obj; } // destroy
void DoSomething() override {
real_obj->DoSomething(); // here we call the method with full type information for real_obj
}
};
class Thing {
std::vector<Aux*> v;
public:
template<typename T> void Add(const T &value) {
v.push_back(new AuxTemp<T>(value));
}
void DoSomethingForAll() {
for(auto &x:v) x->DoSomething();
}
};
Yo can test this with:
class A {
public:
void DoSomething() { std::cout << "A"<< std::endl; }
};
class B {
public:
void DoSomething() { std::cout << "B"<< std::endl; }
};
int main(int argc, char *argv[]) {
Thing t;
t.Add(A{});
t.Add(B{});
t.DoSomethingForAll();
return 0;
}
For each new type you push to your vector, a new derived and specialized wrapper class is made by Add member function, so virtual table can handle calls to DoSomething in order to use the proper and full-aware-of-real-type version.
I think what I propose is a bizarre implementation "type-erasure" (you should google for this term to find more elaborated solutions).

Data structure that can hold multiple types of data

Like the title says, I'm looking for some kind of data structure which will allow me to store any type of class into it that I need at the time. For example:
Foo *foo = new Foo();
Bar *bar = new Bar();
someContainer.push_back( foo );
someContainer.push_back( bar );
someContainer.access( 0 )->doFooStuff();
someContainer.access( 1 )->doBarStuff();
Ideally, as I showed there, it would also allow me to access the contents and use their functions/etc.
I want one of these as I am attempting to create an "invisible" memory management system that just requires a class to inherit my memory manager class, and everything will work automagically.
Here is an example of what I want the code to look like:
template< class T >
class MemoryManaged
{
MemoryManaged()
{
container.push_back( this );
}
void *operator new()
{
// new would probably be overloaded for reference counting etc.
}
void operator delete( void *object )
{
// delete would most definitely overloaded
}
T &operator=( T &other )
{
// = overloaded for reference counting and pointer management
}
static SomeContainer container;
}
class SomeClass : public MemoryManaged< SomeClass >
{
// some kind of stuff for the class to work
};
class AnotherClass : public MemoryManaged< AnotherClass >
{
// more stuff!
};
I hope that my code helps make clear what exactly it is I want to do. If someone knows some kind of already-built data structure that would allow me to do this, that would be awesome. Otherwise, I am currently working on building some kind of shambling zombie of a linked list class that uses templated nodes in order to link any type of class to any other type of class. I still have no idea how I'd get it to work yet, and I would love to be spared the blood, sweat, and tears (and hair) it would take to figure out how to make it work.
Have a common base class for all of your multiple types. Have the data structure hold onto pointers of your base class's type.
Take a look at boost::any and boost::variant.
Would some hybrid of template specialization and double-dispatch help? Something like this:
class IContainable;
class Operation
{
public:
template<class ElementType> void Process(ElementType* pEl) {
// default is an unrecognized type, so do nothing
}
};
class IContainable
{
public:
virtual void OperateOn(Operation* pOperation) = 0;
};
class Foo : public IContainable
{
public:
int GetFooCount() { return 1; }
virtual void OperateOn(Operation* pOperation);
};
// specialization of the operation for Foo's
template <> void Operation::Process<Foo>(Foo* pFoo)
{
std::cout << pFoo->GetFooCount() << std::endl;
}
void Foo::OperateOn(Operation* pOperation)
{
pOperation->Process(this);
}
int main()
{
typedef std::vector<IContainable*> ElementVector;
ElementVector elements;
// configure elements;
Operation oper;
for(ElementVector::iterator it = elements.begin();
it != elements.end(); it++)
{
(*it)->OperateOn(&oper);
}
}
If the list of types in the container isn't known at compile time of the operations of the elements on the container, or they are distributed across modules that are not compiled together, then you could instead use dynamic_cast. You'd define a "IFooHandler" class witha pure virtual method called "HandleFoo" that takes a foo pointer. You'd make Operation::Process virtual and have your operation class derive from both Operation and IFooHandler and implement the operation in HandleFoo(). Your Foo::OperateOn method would dynamic_cast(pOperation) and if the result was non-null, it would call HandleFoo() on the IFooHandler pointer you get from the dynamic cast. Otherwise you'd call the generic Operation::Process and it would have some non-type-specific behavior.
Using a std::vector<T*> should work. Indeed, a new class will be created for each instantiation of MemoryManaged. This means that MemoryManaged<Foo> and MemoryManaged<Bar> will be totally different types. Consequently, the static member container will not be common to these two classes. It will be as if you had the two following classes:
class MemoryManagedFoo
{
MemoryManagedFoo()
{
//Here, you know that 'this' is a Foo*
container.push_back(this); //ok, we add 'this' to a container of Foo*
}
static std::vector<Foo*> container;
};
class MemoryManagedBar
{
MemoryManagedBar()
{
//Here, you know that 'this' is a Bar*
container.push_back(this); //ok, we add 'this' to a container of Bar*
}
static std::vector<Bar*> container;
};
As you can see, the static member is not shared by the two instantiations.
Of course, this solution assumes that MemoryManaged will always be used using CRTP, as you described in your question. In other word, this code will work:
class Foo : public MemoryManaged<Foo> { };
but not this one:
class Foo : public MemoryManaged<Bar>
{
// Here, 'container' is a 'vector<Bar*>' and 'this' is a Foo * --> problem
};