C++: member function address (function pointers) - c++

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));

Related

Assign class function pointer to class structure member [duplicate]

I have a C library with a struct like this:
struct A {
void process(){
doProcess();
};
void (*doProcess)(void);
}
Now, I have a class like
class B
{
public:
B(): a(){
a.doProcess = print();
}
void print(){
// do anything
}
private:
A a;
}
This cannot work since print is a member function and has to be called on an object of B.
Thus I tried to use the boost::bind function:
a.doProcess = boost::bind(&A::print, this)
This does not work either.
I also tried to modify the C Library and replace the function pointer definition with a boost::function definition. But then the compiler complains about not finding "" which is included in "boost/function.h".
Is there a (easy/boost) way of assigning a member function to the struct's pointer?
You simply cannot do this. Member functions have an implicit this argument that is a pointer to the object on which the function is being called. A function that does not take a B* as an argument will never manage to run on a specific B instance and a function that does not take this point as its first argument can never have the same signature as a class method. For more details on this problem and an example of a workaround read:
https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr
Pay attention to the note at the bottom of the answer on how static member functions can be used in such manner.
Pure C++ projects can use std::function & std::bind to achieve what you are asking about, but a C library used by a C++ project cannot work with these types.

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.

Passing a member function of a class to a parameter outside the class

How do you pass a member function of a class as a parameter to another member function of another class?
class theSecondClass
{
public:
void theFunctionReceiver(void (theFirstClass::*Function)(void));
{
// This part is wrong. "Operand of * must be a pointer"
(*Function)();
}
}
class theFirstClass
{
public:
theSecondClass * SecondClassInstance;
void theFunctiontoPass(void)
{
printf("It worked \n");
return;
}
void theFunctiontoCall(void)
{
SecondClassInstance->theFunctionReceiver(theFunctiontoPass);
}
};
Take the assumption that theSecondClass and theFirstClass are both made already. I'm calling theFirstClass->theFunctiontoCall() from somewhere.
I don't get it. When I pass it in, isn't it pass in as a pointer?
I've taken a look at several similar threads around, but I don't understand them fully.
I'm using VS 2013, basic compiler.
When you write this statement:
SecondClassInstance->theFunctionReceiver(theFunctiontoPass);
What you presumably meant was:
SecondClassInstance->theFunctionReceiver(&theFunctiontoPass);
Which should give you a compiler warning that it's an unqualified member reference, which would point out to you that what you are actually writing is:
SecondClassInstance->theFunctionReceiver(&theFirstClass::theFunctiontoPass);
You are getting a pointer to a member function on the class definition. The "this" is not implicit or included in the package. The only way you're going to be able to call it without a class instance is if it is static. (In which case it won't type-check as a member function...it will just be an ordinary function pointer.)
If I'm going to pass in a reference to my class, why would I even need to pass it the function? Couldn't I just call it with, in the case of the link, ButtonObj->Buttonfunc();
The only reason you would use pointers to member functions is to get some kind of abstraction, where one piece of code can call a member function it doesn't need to explicitly name. If you're okay with theSecondClass::theFunctionReceiver knowing the name of theFirstClass::theFunctionToPass and the identity of theFirstClass...then sure, just pass a reference to an instance of theFirstClass and call the method explicitly.
You might want a situation where theSecondClass is going to call any one of a number of member functions on theFirstClass with matching signatures...it just doesn't want to hard-code which one. In that case, then passing a pair of a class reference and a member function can be done. You seem to suspect this doesn't come up too often as useful, and you would be right. Every year I have to go back and look up the syntax for how to call pointers-to-members on a class, because it almost never comes up except in StackOverflow questions:
How to call through a member function pointer?
More likely what you want (and what people asking those SO questions actually want) is to separate concerns so that theSecondClass has a hook to execute something, but doesn't need to know about theFirstClass at all. Look into lambdas, std::function, and std::bind for generalized solutions which you may be able to experiment with to your satisfaction.
Here is an example to show you what that would look like to conveniently wrap up the call abstractly into a std::function. It makes a function object on the spot, that captures the enclosing this pointer so that when it is invoked it calls the method on the object:
#include <iostream>
#include <functional>
class theSecondClass {
public:
void theFunctionReceiver(std::function<void()> const & Function) {
Function();
}
};
class theFirstClass {
private:
theSecondClass * SecondClassInstance;
public:
void theFunctiontoPass() {
std::cout << "It worked\n";
}
void theFirstClass::theFunctiontoCall() {
SecondClassInstance->theFunctionReceiver(
[this]() {theFunctiontoPass();}
);
}
};
int main() {
theFirstClass tfc;
tfc.theFunctiontoCall();
}
Note this is C++11, which I suggest using if you're not already. Less convenient notations and mechanisms exist in C++98, though.
This corrects problems with your code that go beyond the issue you mention. Please review writing a Minimal, Complete, Verifiable Example. It should be possible to paste your provided code into a compiler and see only the error you wish to discuss.
This adds semicolons after the ends of class definitions
This removes the semicolon after method declarations when you are supplying bodies in the class
You needed various forward definitions to get it to work as you had it, this doesn't require them
When a function takes no parameters, it's customary to define as void foo() not void foo(void). return; as the last line of a function returning no value is kind of superfluous as well.
Avoid writing new C++ code using printf, learn iostreams
Bias member variables to being private or protected.
On StackOverflow code samples try and keep them short and not need scroll bars; it's best to not give opening braces their own line (most of the time)
While naming is subjective, I'd suggest that giving your class names initial caps is a better idea than giving variables initial caps.

lambda as template parameter with access to 'this' pointer?

I have to create objects of three-four classes, all inherited from one base class, but some of the objects need to have different behavior - like complete change of one function; I can do this through more inheritance and polymorphism, but it doesn't seem like a good idea.
My first solution was to use specialized templates(for every nonstandard case), but then I have though about lambdas as template parameter(like here: Can we use a lambda-expression as the default value for a function argument? ) and use them instead class method(like here: C++11 lambda and template specialization ) - for me it's much better solution, because I only have to pass lambda for every weird situation:
auto default_lambda = [&]() -> int {return this->Sth;};
template<typename functor = decltype(default_lambda)>
class SomeClass{
...
Problem is with this pointer - method which I want to change need access to non-static methods and lambda is defined outside of non-static method. Moreover, I can't pass reference to class to lambda, because it's a template class(or maybe I'm wrong?).
Of course, I can use specialized template or just function pointers, but I really like solution with lambdas and I consider it much more fine than my other ideas.
Is there any way to "avoid" this problem? Or maybe my idea was bad all along?
There are at least three obvious problems with your approach:
The class SomeClass won't get access to private members, i.e. use of this is out of question.
You attempt to bind this from the context but there is no context i.e. nothing bind to. You will have to pass the object to dealt with a function parameter.
You only specified a type of the function object but no instance, i.e. you won't be able to use it later.
That said, it seems you could just use the type of a custom function object type rather than some lambda function (sure, this is absolutely unsexy but in return it actually works):
struct default_lambda {
template <typename T>
int operator()(T const& o) const { return o.x(); }
};
template <typename F = default_lambda>
class SomeClass {
...
};
If you need complete change of one function, you have two choices:
One virtual function, using perhaps local classes + type erasure if you have many such objects and you don't want to create many namespace scope types:
std::function, which can be rebound later if you wish.
Example code for the first solution (you can even make this a template):
std::unique_ptr<my_base2> get_an_object()
{
class impl : public my_base2
{
void my_virtual_function() { blah blah; }
};
return std::unique_ptr<my_base2>(new impl);
}
Both are generally superior to templates in this situation (but without context it is hard to tell).

Help needed in Use of Function pointer in C++

i have made a sample example, in this i'm trying to pass a function as argument i am getting error, could you please help me
typedef void (*callbackptr)(int,int);
class Myfirst
{
public:
Myfirst();
~Myfirst();
void add(int i,callbackptr ptr)
{
ptr(i,3);
}
};
class Mysec
{
public:
Myfirst first_ptr;
Mysec();
~Mysec();
void TestCallback()
{
callbackptr pass_ptr = NULL;
pass_ptr = &Mysec::Testing;
first_ptr.add(2,&Mysec::Testing);
}
void Testing(int a,int b)
{
int c = a+b;
}
};
The type of the callback function you're passing as parameter is not defined as part of a class. You probably should define Testing as static.
You are geting an error because you are pointing to a member function. Pointers to member functions are different. See here:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.1
A member function needs to know what instance it is working with (the this pointer) so it can't be called like any other function. If you moved the callback function out of the class (or made it static, which is similar to moving it out of the class) you could call it like any other function.
A more modern way of doing this is to use functors, e.g. boost::function and something like boost::bind :
C++ Functors - and their uses
how boost::function and boost::bind work
Those can hide the difference between member and global functions.
You are trying to access a member function pointer here, using a simple function pointer typedef, which will not work. Let me explain.
When you write a normal, non-member function (similar to C), the function's code actually exists in a location indicated by the name of the function - which you would pass to a function pointer parameter.
However, in the case of a member function, all you have is the class definition; you don't have the actual instance of the class allocated in memory yet. In such a function, since the this pointer is not yet defined, any reference to member variables wouldn't make sense, since the compiler doesn't have enough information to resolve their memory locations. In fact, member function pointers are not exact addresses; they encode more information than that (which may not be visible to you). For more, read Pointers to Member Functions.