Function pointer in parameter - c++

I need to make a function which adds a function pointer to map. It would be something like this:
bool RegisterFunction (string name, FunctionPointer function).
But I have problem with calling it, because I don't know how to pass function to it instead of result of function (when I call this as here:
RegisterFunction ("run", Run())
it doesn't works, neither works Run without parentheses, nor:
*Run()
&Run()
*Run
&Run
How to fix this?
Edit:
The error is:
parser.cpp|9|error: no matching function for call to
'MCXJS::Parser::RegisterFunction(const char [4], <unresolved overloaded function type>)'|
The RegisterFunction() and Run() functions are in Parser class, which is in MCXJS namespace.
Class body is:
class Parser
{
public:
Parser ();
CVariable RegisterFunction (FunctionPointer);
bool RegisterErrorHandler (ErrorType, ErrorHandlerPointer);
CVariable Run (std::string);
bool AlwaysDefaultErrorHandler;
int MaxCallStackSize;
private:
std::map <std::string, FunctionPointer> ExternalFunctions;
std::map <ErrorType, ErrorHandlerPointer> ErrorHandlers;
ErrorHandlerPointer DefaultErrorHandler;
};
And the parser.cpp file:
Parser::Parser ():
AlwaysDefaultErrorHandler (true), MaxCallStackSize (4)
{
RegisterFunction ("run", Run);
};
CVariable Parser::Run (std::string path)
{
return 5;
};
Typedefs:
typedef CVariable (*FunctionPointer) (std::string);
typedef void (*ErrorHandlerPointer) (ErrorData);

Run is a non-static member function, not a normal function so either you are registering something of the wrong type or you need to change your typedef to refer to a pointer-to-member.
E.g.
typedef CVariable (Parser::*FunctionPointer) (std::string);
Then the correct way to form a pointer-to-member would be:
RegisterFunction("run", &Parser::Run);
Note that you have to use either the .* or ->* operator with an object or object pointer respectively to call the member function through the pointer-to-member.

RegisterFunction ("run", Run)
is the correct method. What error are you getting using that?
I suspect that the problem is not with how you are calling RegisterFunction, but with how you are defining it. You give us this:
RegisterFunction (string name, FunctionPointer function).
but leave out the declaration of FunctionPointer. It would need to be defined something like:
typedef void (*FunctionPointer)()
Assuming that Run is defined as:
void Run();
Note that for this to work, All of the functions you use with RegisterFunction must have the same signature.
UPDATE: Based on the error message you provided in the comment, it seem the problem is that you have more than one "Run" function, and the compiler don't know which one you want to pass. (Unfortunately, I'm not sure how you clarify it, so you may wish to rename one of them)
One thing you may want to try is:
RegisterFunction (std::string("run"), Run);
Given an exact match for the first parameter, it may be able to choose which Run function based on which matches the signature in FunctionPointer.
UPDATE2 :
You will either need to make Parser::Run() a static function, are change the declaration of FunctionPointer to:
typedef CVariable (Parser::*FunctionPointer) (std::string);

You can just pass the name of the function without any decoration or any parentheses:
RegisterFunction(name, Run);
However, the following should also work:
RegisterFunction(name, &Run);

Related

C++ passing overloaded operator() of class as function pointer

So I got myself onto shaky ground by insisting on making a C++ class immitate a regular function. The class overloads the function operator, making it a functor, of course. This all works fine, until you want to pass the function pointer of this functor.
Naturally, I want to let the compiler know that we know what we're doing (lol), by doing a reinterpret_cast of this pointer. However, how do I get the address of this particular member function, since it is an overloaded operator. How does one get the address of that?
UPDATE: You asked for an example. Here is a minimal one.
So I have an interface, which I cannot change. It looks like this;
typedef void (*some_callback_t)(SomeType);'
void someFunc(some_callback_t);
Now, this is quite straight-forward; the API is setting some callback function pointer. So, the idea was to implement the callback as a functor class, by overloading the operator(), like so, as usual.
class Bah {
void operator()(SomeType);
};
Here comes the question; seeing as I cannot change the API used (the function that expects a function pointer of a certain signature), how can I then get the address of the member function and pass that?
I suspect it goes something like;
someFunc(reinterpet_cast<some_callback_t>( ? ? ? )); to make sure that the compiler won't barf at me.
Supposing that you have to use a function pointer, and that your functor has no state, you can use a lambda as glue:
void takesFunctionPointer(void (*)());
struct MyFunctor {
void operator()();
};
// ...
takesFunctionPointer([] { return MyFunctor{}(); });
How does one get the address of that?
In the same way as any other member function. The name of the function is class_name::operator(). An example:
struct class_name {
void operator()(){}
};
void (class_name::*member_function_pointer)() = &class_name::operator();
class_name instance;
(instance.*member_function_pointer)(); // in a block scope
Naturally, I want to let the compiler know that we know what we're doing (lol), by doing a reinterpret_cast of this pointer.
That's usually not what one would want to do.

Definition of Function Pointers

i am working with an sdk, where i have to define a call-back function, the problem is, that the "sample" code are shipped with global functions and a very procedural approach. To bring it into a structure, i was creating classes. But i couldn't get the argument syntax right, when defining and declaring it O_o
So here is my working example:
In my code.h:
void (*MessageHandler)(int msgType, char* msg){printf("\n%s\n", msg);}
this works fine, when i call in my code.cpp
void (*opFunc)(int msgType, char* msg) = MessageHandler;
But i want to do the definition in my cpp, and i couldn't find the syntax, normally it should be:
void (*Code::MessageHandler)(int msgType, char* msg){
printf("\n%s\n", msg);
}
But this doesn't work and i couldn't find any hint how to fix it. Would be nice to get a hint!
Since it is a function, define it as you would do with any function:
void Code::MessageHandler(int msgType, char* msg){
printf("\n%s\n", msg);
}
Its name, Code::MessageHandler is actually a function pointer of the right type. This works as expected if Code is a namespace, if it is a class, you'll have to declare it static to get an unbound reference.
Also, consider using typedef to make the source code more readable.
It looks like you're trying to define a function for a function pointer within your Code class? You can just create a function (either static member or global function) and use the name of that function as a pointer.
void Code::MessageHandler( int msgType, char* msg ){
printf( "\n%s\n", msg );
}
// Create a function pointer called fn to point at a static function
void (*fn)( int, char * ) = &Code::MessageHandler;
Note again, that this won't work if MessageHandler is not a static function, otherwise you'd be dealing with member function pointers, which are very different from function pointers.
If you wanted Code::MessageHandler to itself be a function pointer, then you'd assign it to a global function upon construction.

C++ runtime member function access by string name

I have two classes:
class MyClassInfo {
public:
void AddMethod(std::string name, void* pointer); // I don't know what signature should be
}
class MyClass
{
public:
void SetField1(int f1);
int GetFileld1();
private:
int field1;
};
I need to be able to access the methods of MyClass by name (string) during runtime. I don't want to use any libraries (except boost) and/or compiler functionality (such as rtti) to do that.
I don't know which signature I should use in AddMethod method, because I don't know how to transmit the function pointer to the function. This function must be a universal function which allows to add any method. Maybe you know a better variant how to do that without MyClassInfo. Any help will be appreciated.
That is not possible in directly C++. You will have to look at alternatives like creating a map of names to member function pointers. But even that would require consistent method signatures.
Something like
std::map<std::string, int (MyClass::*)(void*))
for instance. Your AddMethod signature would then look like this
void AddMethod(std::string name, int (MyClass::* pointer)(void*));
and you would call it like this
info.AddMethod("someMethod", &MyClass::someMethod);
If all functions you want to pass through AddMethod have the same signature (possibly after binding some of the arguments), you can use this signature:
void AddMethod(std::string name, boost::function<int ()> func);
and use like this:
info.AddMethod("GetFileId1", std::bind1st(std::mem_fun(&MyClass::GetFileId1), &MyClassInstance);
If the functions have different signatures, you could store them using boost::function_base:
void AddMethod(std::string name, boost::function_base func);
and you use it like above. The challenge is now to find out exactly what type is stored in the boost::function object so you can use it.

C++: member function address (function pointers)

I have a class X which has this method:
void setRxHandler(void (*h)(int));
And I want to pass to it a member function that exists in instances of class Y.
void comm_rxHandler(int status);
I tried the following:
x.setRxHandler(comm_rxHandler)
But it get the following compile error (I'm using Qt):
error: no matching function for call to
‘X::setRxHandler(< unresolved overloaded function type>)’
So, how can I do that?
I noticed if I declare comm_rxHandler (class Y) as static, I have no errors. But I want comm_rxHandler as a non-static method. Also I want setRxHandler method (class X) to be generic and not class-specific. So I can't declare that method as:
setRxHandler(void (Y::*h)(int))
How to do that? Can you help me on this?
Thanks!
C++ doesn't support bound methods. To invoke a member function through a function pointer, you need to have two things: an instance of the class and the function pointer.
So setRxHandler(void (Y::*h)(int)) is almost correct. You need to declare it as:
void setRxHandler(Y*, void (Y::*h)(int));
To invoke setRxHandler(), you need to pass it arguments as follows:
Y y;
setRxHandler(&y, &Y::comm_rxHandler);
In the setRxHandler() method, you can invoke the function pointer using this syntax:
void setRxHandler ( Y* y, void (Y::*h)(int) )
{
// ...
(y->*h)(0);
// ...
}
To make generic, you need to abstract the Y parameter away, but this is difficult to get right. Check out Boost.Function for an existing implementation that supports this use case, and many more.
Change your callback to this:
void setRxHandler(std::function(<void(int)>);
Then you can use binders:
setRxHandler( std::bind(&class_name::comm_rxHandler, obj) );
(std::function and std::bind are part of the upcomming next version of the C++ standard. It's quite likely your compiler already comes with them. If not, they might live in namespace std::tr1. If all else fails, you will find them at boost - which is where they were invented - as boost::function and boost::bind.)
You can, however, also pass non-member or static functions to setRxHandler, as well as function objects (which is the result of std::bind).
If your compiler already supports lambda functions (also part of the next standard, but already supported by, e.g., recent versions of GCC and VC), you can also use one of those:
setRxHandler( [](){obj.comm_rxHandler();} );
As it is now, the setRxHandler prototype takes a pointer to a function that doesn't return anything and takes an int. As you have noticed, this won't work with member functions because they can't be called like a normal function (you have to handle the this pointer as well, which means having an instance of that class to call the method on).
To make it both work with member functions and non-specific (generic), you have to either make a base class and have all classes you want to use setRxHandler with derive from that class:
class Base { ... };
class Derived : public Base { ... };
// then for the prototype
void setRxHandler(void (Base::*h)(int)) { ... }
// and you can use setRxHandler for all types that derive from Base, which gives you more control than the second option, which is:
or use templates:
template<typename T>
void setRxHandler(void (T::*h)(int)) { ... }
With the template option, you really have no control over what class will be used with setRxHandler (excluding RTTI), which can be exactly what you want.
You can either make a base class for Y and use that (to avoid being "class specific"), or use templates:
template <class T>
setRxHandler(void (T::*h)(int));
But then this may raise questions of how to use the member function (you tell us if it does).
As others have already mentioned, C++ does not provide this functionality.
Another option you could use is libsigc++ which is widely used in gtkmm, see this example in their tutorial for instance on how to pass pointers to member-functions. Your example could look something like:
// sigc::slot<void, int> is a 'slot' to hold a function with return type void
// and 1 int argument.
void setRxHandler(sigc::slot<void, int> slot);
void comm_rxHandler(int status);
//sigc::mem_fun() can convert a member function to a function slot.
x.setRxHandler(sigc::mem_fun(*this, &X::comm_rxHandler));

copying pointer to member functions from a structure

I have my code organized as following
class MyClass
{
public:
typedef void (MyClass::Ptr2func)();
}
struct abc
{
MyClass::Ptr2func ptr;
bool result;
}
void main()
{
MyClass myCls;
abc var;
//here is a lot of decision making code and pointer initializations
//I want to copy the pointer to function in another variable
MyClass::Ptr2func tempPtr;
tempPtr=var.ptr;
}
When I try to copy the var.ptr into tempPtr it gives me a compilation error that the argument list is missing. Also it gives me compilation error on myCls.*(var.ptr()); Is there a precedence issue? I have tried using parenthesis but nothing works. I hope someone can help me out on this.
Thanks and regards,
Saba Taseer
I believe that the problem is that your typedef
typedef void (MyClass::Ptr2func)();
Is not defining a typedef for a pointer to member function, but for a member function type. The typedef for a member function pointer would be
typedef void (MyClass::* Ptr2func)();
Notice the explicit pointer involved here. The type
typedef void (MyClass::Ptr2func)();
is actually a typedef for the type of a member function inside of MyClass that takes no arguments and returns void.
As for your final question, the proper syntax for calling a pointer to a member function is (I believe)
(myCls.*var.ptr)()
Notice that you must parenthesize the expression (myClass.*var.ptr) before trying to call it as a function, since the code
myCls.*(var.ptr())
Means "dereference the pointer-to-member returned by var.ptr() relative to object myCls.
Hope this helps!
This:
typedef void (MyClass::Ptr2func)();
defines a function type. The MyClass:: is completely extraneous in that definition; the final type is void (). (Why? You're in MyClass, so MyClass:: is treated as reinforcement that you want the typedef Ptr2func to belong to MyClass, not as a statement that you want the type to designate a member function.)
You want this:
typedef void (MyClass::*Ptr2func)();
which defines a pointer to a member function.
You're asking about compilation errors.
As I'm writing this your code does not have semicolong after each class definition.
Also, just about any other compiler than MSVC will react to void main; use standard int main.
As an utter beginner (making those kinds of mistakes) it's not a good idea to use member pointer.
Simply don't, but instead explain what you hoped to achieve by that.
Cheers & hth.