I have a method that is invoked a lot in my code with this signature:
void foo (std::function<void(int)> func, int a) {
func(a);
}
I can easily pass a function like this to the method:
static void bar(int a);
foo(bar, 42)
Also, if I have a class instance, I can pass my the function pointer to my instance roughly like this ugly snippet:
class Baz {
bar(int a) {...}
callFoo() {
foo(std::bind(&Baz::bar, this, _1);
}
}
However, in my app, I often need to invoke foo in places where I hold a pointer to an object that has a valid member function which could serve as an argument to foo. I don't really want to give every class that happens to hold a valid pointer a method that invokes 'foo'. In fact, I would prefer that those classes don't even know about foo.
I want a method that looks like this:
template<class T>
static void callFooSugar(T* ClassPointer, [What goes here?] ClassMethod);
So I could do this:
Baz MyBaz;
callFooSugar(&MyBaz, bar);
Is there a way to write callFooSugar without resorting to macros? I am compiling with C++11.
Related
I'm thinking of the way how to call most base virtual function given a pointer to a base class and pointer to most base virtual function of that class. This call should happen in outher module, e.g. Invoker, this module shouldn't know anything about class and function it's calling.
Need to build event-emitting system that will not respect virtuality of the callbacks and call exactly that target's function which address was passed to Invoker.
I want to make mandatory for derived classes to use their own callbacks and subscriptions and in general don't do virtual callback in the hierachy. If client still needs something alike, he can try to use virtual handlers in non-virtual callback of the base class.
I tried all kind of casts. Doesn't help, maybe I use them wrong...
#include <iostream>
class A
{
public:
virtual void Foobar() { std::cout << "A" << std::endl; }
};
class B : public A
{
public:
virtual void Foobar() { std::cout << "B" << std::endl; }
};
using CallbackType = void(A::*)();
void Invoker(A* target, CallbackType function)
{
(target->*function)();
}
int main()
{
A a;
B b;
Invoker(&a, &A::Foobar);
Invoker(&b, &A::Foobar);
b.A::Foobar(); // how to make similar call inside Invoker(&b, &A::Foobar) ?
return 0;
}
The output will be:
A
B
A
I want Invoker somehow to call the most base function, so expected output is:
A
A
A
It's not possible to do this with a pointer to member function. Instead, a lambda would be more appropriate:
Invoker(&b, [](A& a) { a.A::Foobar(); });
You need to rewrite Invoker as a template so that it can accept both lambdas and pointers to members:
template <class F>
void Invoker(A* target, F&& function) {
std::invoke(std::forward<F>(function), *target);
}
From what I know, it's impossible.
You can't call a virtual function in a non-virtual manner through a member function pointer.
Well, the lambda solution presented in the other answer is indeed the way to go.
However, I found a way to do what you want ... sort of. The downside is that it involves a slicing copy of the object:
void Invoker(A* target, CallbackType function)
{
(static_cast<A>(*target).*function)();
}
or
void Invoker(A target, CallbackType function)
{
(target.*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));
?
Let's say, I've two classes
class A
{
public:
void foo( /* ............. */ );
};
class B
{
public:
void bar();
};
I want to know, if it's even possible to pass to the foo method a pointer of bar method, store it in A and run bar later from A. I should say, that A won't know, what class bar is a member of!
I'd appreciate much if you show me the syntax or some link with not that complicated description of the topic.
DESCRIPTION
I'm designing an observer pattern for C++. I want to subscribe B to some events of A. e.g. this code should be in an instance of B
// pseudo code
A* observable = new A();
observable->addEventListener ( 'eventTitle' , functionName );
And when eventTitle occurs A calls functionName of B
There is a couple of methods how to call a pointer to member function, hiding it's origin:
Use std::function and std::bind:
class B {
double Sqrt(int what) { return std::sqrt((double)what); }
};
// in A:
std::tr1::function<double (int)> fn;
fn = std::tr1::bind(&B::Sqrt, &operations, std::tr1::placeholders::_1);
fn(3.1415);
Use a functor, which will wrap the pointer to member function and the object, on which it's to be called, togeter. (This is a bit complicated, though, and in principle is just a subset of what std::function does).
Derive B from an abstract interface IFn and pass B as IFn reference to Foo. Foo will know what to call - a virtual Do() function of the interface.
How can A use a member function of B without knowing anything about it? To call it, you need an object, which has to be o type B (or subtype), so A must have this knowledge.
If you make bar() a static function, you can use regular function pointer (void (*)()) or std::function<void ()> (boost::function for older C++) - of which I would strongly recommend the latter.
That won't work unless bar is declared as a static member of B. You should take into account that you would need an instance of B in order to call any non-static methods.
(Check the C++ FAQ chapter on pointer-to-member-functions for a deeper explanation.)
UPDATE: if you want to implement an observer pattern, you can declare an interface (pure abstract class), say Observer, that A knows and use pointer-to-member-functions to map your events to the corresponding Observer methods.
Example:
A observable;
observable.addEventListener ( 'eventTitle' , &B::functionName );
B observer;
observable.registerObserver(&observer);
Use something like:
class A
{
public:
void foo( /* ............. */ );
void SetObs(CObs *pObs)
{
m_pObs = pObs;
}
private:
CObs *m_pObs;
};
class B : public class CObs
{
public:
virtual void bar();
};
class CObs
{
public:
virtual void bar() = 0;
};
And whenever you need bar() function call m_pObs->bar(). Also derive all slasses like B from CObs and override the function bar().
I have a function with void * as one of its parameters (the void is used as a generic object). But to be able to call a function in that generic object, I need to cast it first, and for that I need to know what type the class is. And I wanted to know, is it possible to pass a class or some information that allows me to cast the object as a function parameter?
By any chance have you looked into Templates?
An example would be something such as
class SomeClass
{
public:
template<typename CastClass>
void DoSomething(void* someArg)
{
(CastClass)someArg;
}
};
Usage:
class A{ }; // Some random test class
SomeClass test;
A a;
test.DoSomething<int>(&a); // The template parameter can be anything.
// I just have int to make it a smaller example.
I have a class
class fobj{
public:
fobj(int i):id(i) {}
void operator()()
{
std::cout<<"Prints"<<std::endl;
}
private:
int id;
};
template<typename T>
void func(T type)
{
type();
}
If I invoke func like
Method 1:
func(fobj(1));
the message I wanted to print is printed.
I was always thinking I needed to do something like
Method 2:
fobj Iobj(1); // create an instance of the fobj class
func(Iobj); // call func by passing Iobj(which is a function object)
How does Method 1 work? I mean what exactly happens?
And how is a call made to the operator() in class fobj ?
One thing to note is that this works because your template class is taking an object by value:
template<typename T>
void func(T type) // this takes a T by value
...
because of this, it can take either an lvalue (such as an actual variable) or an rvalue (such as the temporary).
If for some reason you did want to limit func to only taking an lvalue, you could modify the function to using pass by reference:
template <typename T>
void func(T &type) // this takes a T by reference
...
using pass by reference does allow the side effect of the function being able to modify the object.
In func(fobj(1)), fobj(1) creates a temporay fobj from the literal int 1. This temporary is used to initialized the function parameter type (there's an implicit copy which the compiler may elide), and in the body of the function operator() is invoked on the function object.
I think that naming the function parameter type is a bit misleading. type is the name of the T instance (in this case a fobj) that is the function parameter.