Call C++ member function pointer without knowing which class - c++

I am trying to call a member function, possibly given the object pointer, without knowing what class the member function is from. Is this possible?
Basically I want something like the following to work.
class Foo{
public:
Foo(void* object): obj(object) {}
void callFunc(void (*func)()){
obj->*func();
}
private:
void* obj;
};
class Bar{
public:
Bar(): foo(this) {}
void callSomeFunc(){
callFunc(someFunc);
}
void someFunc(){
cout << "hi\n";
}
private:
Foo foo;
};
int main(){
Bar bar;
bar.callSomeFunc();
return 0;
}

It looks a lot like an XY-problem. Anyway, let's try to reply to your question as it is.
A function member is bound to the type of the class to which it belongs, unless it's a static one (the latter is treated just like a plain function pointer and you don't even have to pass a pointer to an instance to call it).
Therefore you can make callFunc a function template and let it deduce the type for you:
template<typename T>
void callFunc(void (T::*func)()){
(static_cast<T*>(obj)->*func)();
}
See it up and running on wandbox.
Note that you can incur in errors when you static_cast your obj if its original type (the one you erased to put it in a void *) isn't T.
Here is the full code you can see at the link above:
#include<iostream>
class Foo{
public:
Foo(void* object): obj(object) {}
template<typename T>
void callFunc(void (T::*func)()){
(static_cast<T*>(obj)->*func)();
}
private:
void* obj;
};
class Bar{
public:
Bar(): foo(this) {}
void callSomeFunc(){
foo.callFunc(&Bar::someFunc);
}
void someFunc(){
std::cout << "hi\n";
}
private:
Foo foo;
};
int main(){
Bar bar;
bar.callSomeFunc();
return 0;
}

It's an XY problem. Use a std::function and/or a lambda.
#include <functional>
#include <iostream>
class Foo{
public:
template<class F>
void callFunc(F&& f){
f();
}
};
class Bar : public Foo{
public:
Bar(): foo() {}
void callSomeFunc(){
this->callFunc([this]{ someFunc(); });
}
void someFunc(){
std::cout << "hi\n";
}
private:
Foo foo;
};
int main(){
Bar bar;
bar.callSomeFunc();
return 0;
}

Although I find the solution provided by #skypjack more elegant, here a solution that templates the Foo-class (not "only" the function) as a whole. Thereby the type of obj is known throughout the Foo-class, which might be an advantage (or may be not).
Further, see also a solution that stores the member together with the associated object. Maybe it's helpful in some way:
#include <functional>
#include <iostream>
template<class T>
class Foo {
public:
Foo(T& obj) : _obj(obj) {}
void callFuncOnObj(void (T::*func)(void)) {
auto fn = mem_fn(func);
fn(_obj);
}
private:
T &_obj;
};
class Bar{
public:
Bar() : d(*this) {}
void callSomeFunc(){
d.callFuncOnObj(&Bar::someFunc);
}
void someFunc(){
cout << "hi Bar1\n";
}
private:
Foo<Bar> d;
};
class Foo2 {
public:
Foo2(std::function<void(void)> f) : _f(f) {}
void callFunction() {
_f();
}
private:
std::function<void(void)> _f;
};
class Bar2{
public:
Bar2() : d(std::bind(&Bar2::someFunc,this)) {}
void callSomeFunc(){
d.callFunction();
}
void someFunc(){
cout << "hi Bar2\n";
}
private:
Foo2 d;
};
int main(){
Bar bar;
bar.callSomeFunc();
Bar2 bar2;
bar2.callSomeFunc();
return 0;
}

Related

Select which member function to call at compile time

I have a templated class on some object T. T defines two member functions bar and foo
template<class T>
class A {
public:
void f() {
t_.bar();
t_.foo();
}
private:
T t_;
};
Now I would like be able to tell A (ideally at compile time), to call either foo or bar, but not both. So the idea is to tell A at construction time which member function of T to call.
The solution I have currently in place is to pass a callable void callMember(const T& t) { return t.foo(); } in A's constructor to at runtime call the right member, but I'm wondering if there is a better solution?
You can add a bool template parameter to A that tells it which member function of T to call, and then use a constexpr if on that parameter in the body of f:
template<class T, bool Choice>
class A {
public:
void f() {
if constexpr(Choice) // doesn't strictly have to be constexpr
// if T defines both bar and foo
t_.bar();
else
t_.foo();
}
private:
T t_;
};
Now for some type like:
struct S {
void bar() { std::cout << "bar"; }
void foo() { std::cout << "foo"; }
};
you can do:
A<S, true> a;
a.f(); // calls S::bar
A<S, false> b;
b.f(); // calls S::foo
Here's a demo.
I assume its Ok to have instantiations of A be of different type depending on which method is called. If that is the case I suggest to choose between two types rather than two methods.
Say X is the type with the two methods, then you can do this:
struct X {
void foo() {}
void bar() {}
};
struct Xfoo {
X x;
void foobar() { x.foo(); }
};
struct Xbar {
X x;
void foobar() { x.bar(); }
};
Now the template is:
template<class T>
class A {
public:
void f() {
t_.foobar();
}
private:
T t_;
};
And you either instantiate A<Xfoo> or A<Xbar> rather than A<X>.
I suppose you have more than just one type X, then Xfoo and Xbar can be parametrized on the type to be wrapped.

How to get a C++ template class to invoke another class' methods?

I have class A that needs to invoke the member functions of template class B. Searching around I found this sample code on this site:
#include <iostream>
template<typename T, typename FType>
void bar(T& d, FType f) {
(d.*f)(); // call member function
}
struct foible
{
void say()
{
std::cout << "foible::say" << std::endl;
}
};
int main(void)
{
foible f;
bar(f, &foible::say); // types will be deduced automagically...
}
That came from this answer:
C++ method name as template parameter
But it doesn't do 100% of what I need. How would the above code be re-written so that:
method bar is a public member of a class and not a stand-alone
function
arguments d and f which are getting passed to method bar are
public members of the same class to which bar is a member,
allowing bar to be of type void (void)
object type foible is a class and not a structure (optional)?
[EDIT 1] My own attempt at the rewrite which meets points 1) and 2) is the following, which is wrong:
#include <iostream>
template<class T, void (T::*FType)()>
class foo {
public:
T obj;
FType f;
void bar(void) {
(obj.*f)(); // call member function
} // end bar
}; // end class foo
struct foible
{
void say()
{
std::cout << "foible::say" << std::endl;
}
};
int main(void)
{
foible f;
foo<foible, void (foible::*)()> c;
c.T = f;
c.Ftype = &foible::say;
c.bar(); // types will be deduced automagically...
}
My goal is to have an object of class type 'A' invoke the methods of object of class type 'B', so that when these methods execute the object of type 'B' can use its 'this' pointer to reference its local data. I want to use function pointers inside class type 'A' so that these only need to be specified once, and I don't want one class to have to be derived from another.
You are making that too complicated. Forget about pointers to methods. Currently there is no reason to use them.
Just do something like this:
template<typename F>
void bar(F f) {
doSomething();
f(someArg);
doSomething();
}
int main(void)
{
foible f;
bar([&f](auto x) { f.someMagicMethod(x); } );
return 0;
}
Note this approach is more flexible and readable than playing around with method pointers.
A step by step solution:
all examples uses the following class and foo function
#include <iostream>
class A
{
public:
void foo(){std::cout<<"foo"<<std::endl;}
};
this sample works without template: just calling the calling A::foo with pointer to A and pointer to A::foo:
class B
{
public:
A *a;
void (A::*p)();
void bar()
{
(a->*p)(); //call A::foo
}
};
int main(void)
{
A a;
B b;
b.a = &a;
b.p = &A::foo;
b.bar();
return 0;
}
The following sample added template class T, the pointer to foo method derived from T.
template <class T>
class C
{
public:
T* t;
void (T::*p)();
C(T &o) : t(&o){}
void bar()
{
(t->*p)();
}
};
int main(void)
{
A a;
C<A> c(a);
c.p = &A::foo;
c.bar();
return 0;
}
in the following, the method pointer was templated too, but I don't see how can it be used since you should know how many argument to give it, but anyway:
template <class T, typename F>
class D
{
public:
T* t;
F p;
D(T &o, F pf) : t(&o),p(pf){}
void bar()
{
(t->*p)();
}
};
int main(void)
{
A a;
D<A, void (A::*)()> d(a, &A::foo);
d.bar();
return 0;
}

Is a C++ template able to "forward any class function" from parent class?

class Foo {
public:
void methodA();
};
class ManagedFoo {
Foo fooInst;
public:
void methodA() { doSomething(); fooInst.methodA();}
};
Now I want to make ManagedFoo as a template, managing any class not only Foo, and before any of Foo's function is called, call doSomething first.
template<typename _TyManaged>
class Manager {
_TyManaged _managedInst;
void doSomething();
public:
/*Forward every function called by _managedInst*/
/*How to write this?*/
};
I want to make it the same, make it replaceable between this two class, like this :
Foo* foo = new Foo();
foo->methodA();
Manager<Foo> managedFoo = new Manager<Foo>();
managedFoo->methodA(); //Hope it call Manager::doSomething() first then call _managedInst.methodA();
Can C++11 template do such thing? if answer is yes, how to?
Solution based on operator-> overloading:
#include <iostream>
#include <memory>
class A {
public:
void foo() { std::cout << "foo\n"; }
void bar() { std::cout << "bar\n"; }
};
template <typename T>
class ManagedBase {
std::shared_ptr<T> _inst;
public:
ManagedBase(const std::shared_ptr<T> inst) : _inst(inst) { }
virtual ~ManagedBase() { }
std::shared_ptr<T> operator->() {
before();
return this->_inst;
}
virtual void before() =0;
};
template <typename T>
class ManagedPrint : public ManagedBase<T> {
public:
ManagedPrint(const std::shared_ptr<T> inst) : ManagedBase(inst) { }
virtual void before() {
std::cout << "Said: ";
}
};
int main() {
auto ma = ManagedPrint<A>(std::make_shared<A>());
ma->bar(); // Said: foo
ma->bar(); // Said: bar
}
Something like this?
template<typename _TyManaged>
class Manager {
_TyManaged _managedInst;
void doSomething();
public:
_TyManaged* operator->() {
doSomething();
return &_managedInst;
}
};
This can solve your problem. But I'm still not sure what you want to do with your Manager class.
class Foo {
public:
void methodA();
};
template<typename T>
class ManagedFoo : public T {
public:
// some further extensions
};
And of course in this way you change the semantic of the Foo class by the manager from:
It has a
to
It is a
So I'm not sure if this is true in your case.

Template member function (on type T) of non-template class T

I would like to do something like:
class A {
public:
void f();
private:
void g() { };
};
class B {
public:
void f();
private:
void g() { };
};
template<typename T>
void T::f() {
g();
}
int main() {
A a;
B b;
a.f();
b.f();
}
however T::f() does not compile.
Possible workarounds could be making f() non-member:
template<typename T>
void f(T* t);
Or using CRTP: http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
But is there no C++ syntax to do as above?
EDIT: I have a big function f() whose code is shared by the 2 classes A and B. A and B have the same interface, which f() uses. However, because we are not using runtime polimorphism (i.e, virtual functions), the corpus of f() needs to be instantiated twice at compile time, once for A and once for B. Templates are made exactly for this purpose. The function f(), in my case, should be template function whose template type is the type of *this.
Free function is the correct answer. You should prefer free functions over member functions anyway, for this exact reason: you extend the interface without intruding on the class.
In this case, a free function with an unconstrained template is a bit ugly, because you only need it to work for two cases, not all cases. You should do something like this:
namespace detail
{
template <typename T>
void f(T* t)
{
// implement stuff
}
}
void f(A* x)
{
detail::f(x);
}
void f(B* x)
{
detail::f(x);
}
Now you can restrict access to that function via overloading.
Here is an example using a free function and retaining the instance.f() syntax. The function needs to be marked as a friend in order to access the private methods:
#include <iostream>
namespace details
{
template<class T>
static void f_impl(T* _this)
{
_this->g();
}
}
class A {
public:
template<class T> friend void details::f_impl(T*);
void f()
{
details::f_impl(this);
}
private:
void g()
{
std::cout << "A" << std::endl;
}
};
class B {
public:
template<class T> friend void details::f_impl(T*);
void f()
{
details::f_impl(this);
}
private:
void g()
{
std::cout << "B" << std::endl;
}
};
int main() {
A a;
B b;
a.f();
b.f();
}

C++. Class method pointers

There is a class
class A {
public:
A() {};
private:
void func1(int) {};
void func2(int) {};
};
I want to add a function pointer which will be set in constructor and points to func1 or func2.
So I can call this pointer (as class member) from every class procedure and set this pointer in constructor.
How can I do it?
class A {
public:
A(bool b) : func_ptr_(b ? &A::func1 : &A::func2) {};
void func(int i) {this->*func_ptr(i);}
private:
typedef void (A::*func_ptr_t_)();
func_ptr_t_ func_ptr_;
void func1(int) {};
void func2(int) {};
};
That said, polymorphism might be a better way to do whatever you want to do with this.
Add a member variable
void (A::*ptr)();
set it in the constructor
ptr=&A::func1;
(or use the initializer list) and call it in methods of A:
(this->*ptr)();
I compiled and ran this code. The various members need to be public so you can pass them into the constructor. Otherwise, here you go.
However, I agree with other posters that this is almost definitely a bad thing to do. ;) Just make invoke pure virtual, and then make two subclasses of A which each override invoke().
#include <iostream>
using namespace std;
class A;
typedef void(A::*MyFunc)(int) ;
class A {
public:
A() {}
A(MyFunc fp): fp(fp) {}
void invoke(int a)
{
(this->*fp)(a);
}
void func1(int a) { cout << "func1 " << a << endl; }
void func2(int a) { cout << "func2 " << a << endl; }
private:
MyFunc fp;
};
int main()
{
A* a = new A( & A::func1 );
a->invoke(5);
A* b = new A( & A::func2 );
b->invoke(6);
}
See boost::function for a way to handle function and class member pointers in a more OO/C++ manner.
For example (from the documentation) :
struct X
{
int foo(int);
};
boost::function<int (X*, int)> f;
f = &X::foo;
X x;
f(&x, 5);
I suggest you use functor(or function object), rather than function pointer, because the former is safer, and function pointer can be difficult or awkward to pass a state into or out of the callback function
A functor is basically a re-implementation of operator() of class A, for very detailed description please refer to Wikipedia: http://en.wikipedia.org/wiki/Function_object
The code should be something like this:
class A {
public:
A() {};
void operator()(int function_index, int parameter) {
if(function_index == 1)
func1(parameter);
else if(function_index == 2)
func2(parameter);
else
{ //do your other handling operation
}
}
private:
void func1( int ) {};
void func2( int) {};
};
By using that class:
A a;
a(1, 123); //calling func1
a(2, 321); //calling func2
Why do you think it's a bad thing to do. I just need one function pointer and I don't want to create two subclasses for this. So why is it so bad?
Some example...
class A; // forward declaration
typedef void (A::*func_type)(int);
class A {
public:
A() {
func_ptr = &A::func1;
}
void test_call(int a) {
(this->*func_ptr)(a);
}
private:
func_type func_ptr;
void func1(int) {}
void func2(int) {}
};