Passing a function as an argument in c++ - c++

I have the following call:
void Derived::GetEntry(Skill&);
InorderTraverse(GetEntry);
Which calls
void Base<ItemType>::InorderTraverse(void Visit(ItemType&)) const
Attempting to compile as written generates
error C3867: 'Derived::GetEntry': function call missing argument list; use '&Derived::GetEntry' to create a pointer to member
Using &Derived::GetEntry generates
cannot convert parameter 1 from 'void (__thiscall Derived::* )(Skill &)' to 'void (__cdecl *)(ItemType &)'
Changing the declaration to static void GetEntry... fixes these problems, but creates a new set of problems (namely that I can't access non-static objects (nonstatic member reference must be relative to a specific object)
I have a similar traversal operation that works fine with a static declaration, since the called function just displays information about each object on which it is called.
I've been searching for a few days now for an answer, and I feel like it's something simple. Is there a way to use a nonstatic function as a parameter in another function call?
The complete code is: https://github.com/mindaika/SkillTree

Edit: Inserted full working example instead.
I suggest you use the std function pointers instead.
For instance:
#include <functional>
void main()
{
class TheClass
{
public:
TheClass()
{
m_function = ( std::tr1::bind(&TheClass::run, this) );
};
void run()
{
// stuff to do
};
std::tr1::function<void ()> m_function;
};
TheClass theclass;
theclass.m_function();
}
m_function (); // call function

As I mentioned in my question, I was trying to get around the "memory leak" caused by using a static variable (it's not actually a leak, since statics are destroyed, but not until after the leak detector runs). I ended up using a modification of the encapsulated pointer described here: C++ freeing static variables

Related

How can I execute a function pointer that's pointing to a class method inside a template function?

I want a function that can be called inside of another class which has a single input parameter of type void function pointer. Inside the function, the function pointer should execute the function to which it's pointing.
// inside TestClass.h
class TestClass
{
public:
template<class UserClass>
static void TestingFctPtrStatic(void (UserClass::* TestFunction)(void), UserClass* Object);
};
template<class UserClass>
inline void TestClass::TestingFctPtrStatic(void (UserClass::* TestFunction)(void), UserClass* Object)
{
Object->TestFunction();
}
Calling the function inside the constructor of TestClass like this gives me the following compile error:
// inside TestClass.cpp
TestClass::TestClass()
{
TestClass::TestingFctPtrStatic<TestClass>(&TestClass::PrintStuff, this);
}
With PrintStuff():
void TestClass::PrintStuff()
{
std::cout << "Printing stuff!" << std::endl;
}
error C2039: 'TestFunction': is not a member of 'TestClass'
message : see declaration of 'TestClass'
message : see reference to function template instantiation 'void TestClass::TestingFctPtrStatic(void (__cdecl TestClass::* )(void),UserClass *)' being compiled
with
[
UserClass=TestClass
]
Edit:
I fixed it by using more parentheses in the implementation:
template<class UserClass>
inline void TestClass::TestingFctPtrStatic(void (UserClass::* TestFunction)(void), UserClass* Object)
{
(Object->*TestFunction)();
}
void(UserClass::* TestFunction)(void)
This is not a pointer to a function. It is a pointer to a class method.
TestFunction();
You can't just call a class method out of thin air. You need an object, an instance of the class, whose method gets called. If p is a pointer to a UserClass, in other words:
UserClass *p=(points to somewhere);
then you would invoke its method using this syntax:
(p->*TestFunction)();
It is unclear from your question's description where the object whose method gets invoked comes from, so you need to figure it out, yourself, based on all the other information you have but was not included in the question. In some form or fashion you'll need to find a UserClass object, somewhere -- either passed in as an additional parameter, or it's lying around, somewhere, in the general vicinity -- and then you can use the TestFunction pointer to invoke this object's method.
This is fundamental to C++, provided that this is a class method. If this PrintStuff is a static class method, then this would be, indeed, a plain old function pointer:
void (*TestFunction)();
And it would get invoke, via a pointer, no differently than any other function.

How to handle class function pointer

I want to be able to use a member variable to hold the address a function to call
I got the error:
cannot convert 'void (TestClass::*)(bool)' to 'void (*)(bool)' in
assignment
TestClass.cpp
#include "TestClass.h"
TestClass::TestClass()
{
_myFctPtr = &setFired;
}
void TestClass::setFired(bool isFired)
{
_fired = isFired;
}
void TestClass::updateValue()
{
(_myFctPtr)(true);
}
bool TestClass::getFired()
{
return _fired;
}
TestClass.h
#pragma once
class TestClass
{
private:
bool _fired = false;
protected:
void (*_myFctPtr)(bool);
public:
TestClass();
void setFired(bool);
void updateValue();
bool getFired();
};
The error:
cannot convert 'void (TestClass::*)(bool)' to 'void (*)(bool)' in assignment
Is showing you that pointers to class member functions have a different type from regular function pointers. This is because, in addition to the regular function arguments and return type, these functions are differentiated by the object they are called on (i.e. their this), which must be provided when invoking them.
Specifically, for a pointer to a function on TestClass which accepts a bool argument as shown here, you need to to define your field as the type void (TestClass::*)(bool):
void (TestClass::*_myFctPtr)(bool);
You can call this like so, assuming you want to invoke the method on this:
((this).*(_myFctPtr))(true);
This article provides additional useful information and advice on better, cleaner ways to invoke pointers to member functions - e.g. using std::invoke for cleaner syntax than what I provided above - but this is the bare minimum to quickly solve your issue.

Unknown Syntax void (Type::m_function)()

I am currently reading through some code and came across a few lines I do not understand.
First
void Foo()
{
(((Type*)parent)->*m_function)();
}
As far as I can tell they are casting the parent to Type and then calling a dereferenced function? I am not sure I have seen the ->*m_function before.
Also I can not see where m_function is declared perhaps here? Which contains more syntax I do not understand. Is it declaring a function that returns void and takes a parameter of a function? But where is the function name?
class Foo()
{
void (Type::*m_function)();
};
It's calling a member function using a pointer to this function: C++ Call Pointer To Member Function
Yes, void (Type::*m_function)(); declares m_function member of type "member function of Type taking 0 args and returning void"

QtConcurrent with member function

I create a QFuture that I want to use to parallelize calls to a member function. More precisely, I have a class solveParallel with .h :
class solverParallel {
public:
solverParallelData(Manager* mgr_);
virtual ~solverParallel(void);
void runCompute(solveModel * model_);
bool resultComput();
private:
Manager *myMgr;
QFuture<bool> myFutureCompute;
};
where the methode runCompute() is creating the myFutureCompute member. .cpp looks like
solveParallel::solveParallel(Manager* mgr_)
:m_mgr(mgr_)
{
}
solverParallel::~solverParallel(void){}
void solverParallel::runCompute(solveModel* model)
{
futureComput = QtConcurrent::run(&this->myMgr,&Manager::compute(model));
}
bool solverParallelData::resultComput()
{
return m_futureComput.result();
}
Include(s) are all right. Compilation fails, on line
futureComput = QtConcurrent::run(&this->myMgr,&Manager::compute(model));
with this error:
Error 44 error C2784: 'QFuture<T> QtConcurrent::run(T (__cdecl *)(Param1),const Arg1 &)' : could not deduce template argument for 'T (__cdecl *) (Param1)' from 'Manager **' solverparallel.cpp 31
In addition, on mouse info for '&Manager' in same line of code stands: Error: a nonstatic member reference must be relative to a specific object.
Do you see where is the trick? Thanks and regards.
From the official documentation :
QtConcurrent::run() also accepts pointers to member functions. The
first argument must be either a const reference or a pointer to an
instance of the class. Passing by const reference is useful when
calling const member functions; passing by pointer is useful for
calling non-const member functions that modify the instance.
You are passing a pointer to a pointer. Also notice that you cannot pass the arguments the way you do, but as extra arguments in the run function. The following should work:
futureComput = QtConcurrent::run(this->myMgr,&Manager::compute, model);

Providing an instanceable class's method as a function pointer?

Here is what I'd like to do. I have a function pointer which wants a function like this:
void func(int a);
so I have a class:
class Foo {
public:
void func(int a);
};
Foo *foo = new Foo;
something->setFunction(foo->func);
or in my case:
testWidget[count] = new TestWidget;
testWidget[count]->eventMouseClick.addHandler(testWidget[0]->silly);
But this gives me:
Error 5 error C3867:
'TestWidget::silly': function call
missing argument list; use
'&TestWidget::silly' to create a
pointer to
member c:\users\josh\documents\visual
studio
2008\projects\agui\alleg_5\main.cpp 190
Is there a way I could make this work without using a static function?
Thanks
Is there a way I could make this work without using a static function?
No. You can't convert a pointer to member function to an ordinary function pointer.
If the callback accepted any callable object (or a std::function, for example), then you could bind the object to the member function and pass the result of that; unfortunately, you can't convert that result to an ordinary function pointer, though.
Your question is not very clear to me. But the error message from the compiler makes me feel that probably you want something like this something->setFunction(&foo->func);
An example might help in case of overloads
struct T{
void func(int){}
void func(double){}
};
void f(void (T::*f)(int)){}
void f(void (T::*f)(double)){}
int main(){
void (T::*fi)(int) = &T::func;
void (T::*fd)(double) = &T::func;
f(fi);
f(fd);
}