function pointer from one class to member function of any class - c++

I'm having difficulties defining a function pointer that can point to any member function (not just member functions for the specified class).
For instance, C++ forces me to specify the class that a function pointer to a member function would point to:
typedef void (Foo::*MyFunctionPointerTypeName)(int);
but what if the class member function that this function pointer is going to point to isn't in Foo? How then would I write this, or what alternative approach could I use?
Update: For anyone looking for a quick answer on how to accomplish this with a C++11 std::function (as tutorials on the subject seem to assume alot of the reader):
Definition (from within Foo):
std::function<void(int)> _fun;
Binding (from any class):
objFoo->_fun = std::bind(&SomeOtherClass::memberFunction,
this, std::placeholders::_1);
Calling it (from within Foo)
if(_fun != nullptr) _fun(42);
If your function has no parameters, you can remove std::placeholders::_1. And if your function has two parameters you'll need to also add std::placeholders::_2 as a parameter to std::bind. Similarly for three parameters, four parameters, etc.

You cannot write a member pointer that could point to a member of any class. Remember: one of the arguments of a member pointer is the class instance itself. And pointers are typed, so the type of its arguments is very much a part of the pointer's type.
You can use std::function however, which can store all sorts of callables. How you would actually call it (ie: what parameters you give it) depends on your needs, as you haven't explained what you're trying to do.

Use inheritance:
#include <iostream>
struct Foo {};
struct Bar : public Foo
{
int F0()
{
return 0;
}
};
struct Baz : public Foo
{
int F1()
{
return 1;
}
};
int main(int argc, char **argv)
{
int (Bar::*pF0)() = &Bar::F0;
int (Baz::*pF1)() = &Baz::F1;
int (Foo::*pointer1)() = static_cast<int (Foo::*)()>(pF0);
int (Foo::*pointer2)() = static_cast<int (Foo::*)()>(pF1);
Bar r;
Baz z;
// Pointer to Foo member function calling Bar member function
std::cout << (r.*pointer1)() << '\n';
// Pointer to Foo member function calling Baz member function
std::cout << (z.*pointer2)() << '\n';
return 0;
}
Output:
0
1
Hope it helps.

Related

Deduce the return type of an abstract class method [duplicate]

I would like to store return value of class member function in another class.
This seems to work:
class Foo
{
public:
Foo(int) {} //non default constructor that hides default constructor
unspecified_return_type get_value();
};
class Bar
{
// stores a value returned by Foo::get_value
decltype(Foo().get_value()) value;
};
However there is a reference to default constructor of class Foo, which may not be defined in some cases. Is there any way to do it without explicitly referring to any constructor?
Yup, there is. std::declval was introduced for exactly this reason (not needing to rely on a particular constructor):
decltype(std::declval<Foo>().get_value()) value;
You could do it with the help of std::declval like the example below:
#include <iostream>
#include <utility>
struct test {
int val = 10;
};
class Foo {
public:
test get_value() { return test(); }
};
class Bar {
public:
using type = decltype(std::declval<Foo>().get_value());
};
int main() {
Bar::type v;
std::cout << v.val << std::endl;
}
LIVE DEMO
std::declval<T> converts any type T to a reference type, making it possible to use member functions in decltype expressions without the need to go through constructors.
std::declval is commonly used in templates where acceptable template parameters may have no constructor in common, but have the same member function whose return type is needed.

How to pass a member function to another member function?

My problem is about passing a member function from a Class A, to a member function of a Class B:
I tried something like this :
typedef void (moteurGraphique::* f)(Sprite);
f draw =&moteurGraphique::drawSprite;
defaultScene.boucle(draw);
moteurGraphique is A class, moteurGraphique::drawSprite is A member function,
defaultScene is an instance of B class, and boucle is B member function.
All that is called in a member function of A:
void moteurGraphique::drawMyThings()
I tried different ways to do it, that one seems the more logical to me, but it won't work!
I got:
Run-Time Check Failure #3 - The variable 'f' is being used without being initialized.
I think I am doing something wrong, can someone explain my mistake ?
C++11 way:
using Function = std::function<void (Sprite)>;
void B::boucle(Function func);
...
A a;
B b;
b.boucle(std::bind(&A::drawSprite, &a, std::placeholders::_1));
Member functions need to be called on objects, so passing the function pointer alone is not enough, you also need the object to call that pointer on. You can either store that object in the class that is going to call the function, create it right before calling the function, or pass it along with the function pointer.
class Foo
{
public:
void foo()
{
std::cout << "foo" << std::endl;
}
};
class Bar
{
public:
void bar(Foo * obj, void(Foo::*func)(void))
{
(obj->*func)();
}
};
int main()
{
Foo f;
Bar b;
b.bar(&f, &Foo::foo);//output: foo
}
Can't you make drawMyThing a static function if you don't need to instantiate A, and then do something like :
defaultScene.boucle(A.drawMyThing(mySpriteThing));
?

What is non overloaded pointer to member and overloaded pointer to member?

I am reading C++ programming language by Bjarne Stroustrup. I came across the statement in templates section.
A template argument can be a constant expression (§C.5), the address of an object or function
with external linkage (§9.2), or a non overloaded pointer to member (§15.5).
What is non overloaded pointer to member? Can someone give example?
A non-overloaded pointer-to-member is as the name states -- a pointer to a member that hasn't overloaded a superclass. Here's an example I've just put together of what will and won't work:
#include <iostream>
class Foo {
public:
virtual void printN() { std::cout << 42; }
};
class Bar : public Foo {
public:
void printN() { std::cout << 31; }
};
template <typename T, typename C>
class SomeTemplate {
public:
void PrintData(T d) { C c; (c.*d)(); }
};
int main() {
SomeTemplate<void (Foo::*) (), Foo> t; // Compiles - '42'
t.PrintData(&Foo::printN);
SomeTemplate<void (Bar::*) (), Bar> t; // Compiles - '31'
t.PrintData(&Bar::printN);
SomeTemplate<void (Foo::*) (), Bar> t; // Won't compile, can't convert overloaded pointers
t.PrintData(&Foo::printN);
return 0;
}
In PrintData, an instance of the class is created and the member pointer passed is dereferenced on the instantiated version of the class, resulting in it's underlying function being called.
Templates make this approach somewhat more flexible, but I've yet to find a reason to use code such as this in a real situation however -- if anyone can find a one I'd love to be enlightened..

Member functions vs static functions with object reference

Why would I use a member function when I can pass a static function a reference to an object?
For example:
#include <iostream>
class Widget{
private:
int foo;
public:
Widget(){
foo = 0;
}
static void increment( Widget &w ){
w.foo++;
std::cout << w.foo << std::endl;
}
};
class Gadget{
private:
int foo;
public:
Gadget(){
foo = 0;
}
void increment(){
foo++;
std::cout << foo << std::endl;
}
};
int main(int argc, const char * argv[]){
Widget *w = new Widget();
Widget::increment( *w );
Gadget *g = new Gadget();
g->increment();
return 0;
}
Is this more than a stylistic thing? My understanding is that member functions are created per object instance, while static functions are not -- and since you can make static functions operate on a per instance basis like in the above example, shouldn't it slightly more efficient to create static functions instead of member functions?
Memeber functions are are not created by instance. They have an implicit first parameter which is the this pointer, so they actually look quite similar to your static function.
For example,
struct Foo {
void foo(int i) {}
}
Foo f;
f.foo(42);
Foo::foo(f, 42);
the two last lines do the same. However, it is hard to see how one could implement this with static methods or functions:
struct IFoo {
virtual foo() const {}
};
struct Foo1 : virtual public IFoo {
virtual foo() const {}
};
IFoo* f = new Foo1;
f->foo();
So, besides the syntactic sugar of allowing you to call the methods on an instance with the . operator, you need them for this kind of run-time polymorphism.
It's important because it allows polymorphism; specifically because it's needed for dynamic dispatch, where the method to which to bind the call is determined at runtime by the true type of the object on which it's invoked. A static call always binds to the method on the nominated type, regardless of the runtime type of the object itself.

Can a single function pointer point to multiple classes member function

Here are the requirements posed by my application. I have a class A, that accepts a function pointer say cFunc, Basically in my implementation of A, I have it call cFunc multiple times.
The cFunc pointer itself should point to different functions depending upon the application. Thus for each application I create a class with the same function definition as cFunc, however I cannot assign the class's member function to this pointer
class A {
typedef double (*Def_CFunc)(std::vector<double>);
A(Def_CFunc _cFunc) { // Some implementation}
// Other Functions
};
class B { double someFunc(std::vector<double> b); };
class C { double someOtherFunc(std::vector<double> a); };
int main () {
B firstObj;
C secondObj;
// Depending upon the situation, I want to select class B or C
double (*funcPointer)(std::vector<double>) = firstObj.someFunc; // Error in this line of code
A finalObj(funcPointer);
}
So how do I make it such that any class with a member function of the given format can be used to initialize the class A?
I'm not sure what exactly your requirements are, but it looks like you want an interface (or abstract base class in C++ lingo).
If both B and C inherit from a common base class, you can pass a pointer to this base class and invoke functions on it:
class I { virtual double func(std::vector<double> a) = 0; }
class B : public I { double func(std::vector<double> a); };
class C : public I { double func(std::vector<double> a); };
You can pass an I* pointer to A and just use i->func.
Pointer to member function has different syntax than pointer to ordinary function and can only point to a method of one given class. To be able to point to methods in different classes use boost::function or if C++11 is available use std::function. These can hold any method or function of a given signature.
What you need is std::function together with either std::bind or lambda expressions (or the Boost equivalent of the first two), because member function pointers don't allow you to do that.
You can do it using std::bind + std::function. Lets write some template class wrapper, that takes any static type as input. Then use this wrapper in free function switch_obj. Usage is very simple.
typedef std::function<double(std::vector<double>)> my_foo;
template<class C>
struct switcher
{
static my_foo convert(C* obj)
{
return my_foo( std::bind(&C::someFunc,obj,std::placeholders::_1) );
}
};
template<class T>
my_foo switch_obj(T* obj)
{
return switcher<T>::convert(obj);
}
void main()
{
B firstObj;
C secondObj;
auto f = switch_obj(&firstObj);
A a(f);
}