I have a nested class B inside class A. I need to pass a custom function with one integer argument and return type of void at runtime to class B.
This is how I tried to do it. First I passed the function through the constructor of A. And then to pass it to B, I tried to use pointer to member function. However I can't figure out how to call function foo() inside doStuff().
class A {
void(*f)(int);
A(void(*f)(int)) : f(f) {};
class B {
void(*A::*foo)(int) = &A::f;
void doStuff() {
var = 10;
*foo(var); //Doesn't work
}
};
};
void testFunction(int a) {
//do something
}
A a(testFunction);
What is the correct way to call it? And does this solution make sense as the whole?
Edit: Possible alternative solution:
class A {
A(void(*f)(int)) {
b = B(f);
}
class B {
void(*f)(int);
B() {}
B(void(*f)(int)) : f(f) {}
void doStuff() {
var = 10;
f(10);
}
};
B b;
};
Note that in order to call a pointer-to-function member of A you need an object of type A to call it on. In the example below, the reference to an A object was passed as an argument to B::doStuff.
#include <iostream>
class A
{
public:
void (*f)(int);
A(void (*f)(int)) : f(f) { }
class B {
public:
void (*A::*foo)(int) = &A::f;
void doStuff(A &a) {
(a.*foo)(10);
}
};
};
void testFunction(int a) {
std::cout << "inside testFunction(" << a << ")" << std::endl;
}
int main()
{
A a(testFunction);
A::B b;
b.doStuff(a);
}
Example output: inside testFunction(10).
Related
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 it possible to pass this by default ?
Here is what I currently have
class A
{
public:
template<typename T>
void dowithT(T t) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
a.dowithT(this);
}
};
This function requires passing this from the caller of the function every time. So I wondered if there is a way to encapsulate this task, so that you don't need to pass this to dowithT.
I tried to do something like this:
class A
{
public:
// '= this' doesn't compile
template<typename T>
void dowithT(T t = this) {}
};
class B
{
public:
A a;
B()
{
//Calling 'dowithT' without 'this'
a.dowithT();
}
};
Unfortunately, I can't use templates, so my first solution isn't an option.
Is this possible?
Edit: I gave a concrete answer with my own implementation below. Also with a few mor deatils of what I wanted in the end.
TL;DR No, this is not possible.
this is not the same type in every class, you can't generalize it, so no, not possible.
Additionally, what would this be if doWithT() was called from a non-member function? nullptr?
That's why it isn't possible. You have to use a template.
Instead of B having a member of type A, it can inherit from A, and use something like the "curiously recurring template pattern."
If you cannot make class A a template, you can still do it like so:
class A
{
protected:
template <class T>
void dowithT()
{
T* callerthis = static_cast<T*>(this);
// callerthis is the "this" pointer for the inheriting object
cout << "Foo";
}
};
class B : public A
{
public:
B()
{
dowithT<B>();
// Or A::dowithT<B>();
}
};
dowithT() must only be called by an inheriting class (hence I made it protected), with the template parameter the caller's own type, or you'll break everything.
You may achieve exactly what you want by using a private mixin class to provide the dowithT method that takes no arguments:
#include <iostream>
#include <typeinfo>
class A
{
public:
template<typename T>
void dowithT(T* t) {
std::cout << "Hello, World" << typeid(*t).name() << std::endl;
}
};
template<class Owner>
struct calls_a
{
void dowithT()
{
auto p = static_cast<Owner*>(this);
p->a.dowithT(p);
}
};
class B
: private calls_a<B>
{
friend calls_a<B>;
A a;
public:
B()
{
//Calling 'dowithT' with 'this'
dowithT();
}
};
int main()
{
B b;
}
No, it is not possible. There is nothing really special about this when used as an argument to a function taking T* (template or not), it's just a pointer like any other.
this A is different from this B. In your first code, this refers to the caller, while in the second this refers to the callee. Thus what you want to do isnt really possible.
Here's one possibility, which might, or might not suit your needs:
template<typename T>
class A
{
public:
A(T t) : t(t) {}
void dowithT()
{
cout << "Foo";
}
private:
T t;
};
class B
{
public:
A<B*> a;
B() : a(this)
{
a.dowithT();
}
};
You could use a private method in class B that acts as a relay, and use the constant nullptr as a special value for this, if you want to be able to pass other values:
class B
{
public:
A a;
B()
{
//Calling 'dowithT' with 'this'
innerdo();
}
private:
void innerdo(B *p = nullptr) {
if (p == nullptr) p = this;
a.dowithT(p);
}
};
If you only need to pass this it is even simpler
void innerdo() {
a.dowithT(this);
}
After trying out various things you mentioned, I'd like to give my answer/solution to the problem myself to clarify some details:
#include <iostream>
using namespace std;
#include <functional>
template <typename CallerType>
class AFunctionConstructor{
private:
virtual void abstr()
{}
public:
typedef void(CallerType::*CallerTypeFunc)();
function<void()>* constructFunction(CallerTypeFunc func)
{
CallerType* newMe = dynamic_cast<CallerType*> (this);
return new function<void()>(std::bind(func,newMe));
}
};
class A : public function<void()>
{
protected:
public:
A();
A(function<void()>* func) : function<void()>(*func)
{}
};
// now create ressource classes
// they provide functions to be called via an object of class A
class B : public AFunctionConstructor<B>
{
void foo()
{
cout << "Foo";
}
public:
A a;
B() : a(constructFunction(&B::foo)) {}
};
class C : public AFunctionConstructor < C >
{
void bar()
{
cout << "Bar";
}
public:
A a;
C() : a(constructFunction(&C::bar)) {}
};
int main()
{
B b;
C c;
b.a();
c.a();
cout << endl;
A* array[5];
array[0] = &b.a; //different functions with their ressources
array[1] = &c.a;
array[2] = &b.a;
array[3] = &c.a;
array[4] = &c.a;
for (int i = 0; i < 5; i++) //this usability i wanted to provide
{
(*(array[i]))();
}
getchar();
return 0;
}
Output :
FooBar
FooBarFooBarBar
This is as far as i can press it down concerning examples. But i guess this is unsafe code. I stumbled across possible other and simpler ways to achieve this (other uses of std::function and lambdas(which i might have tried to reinvent here partially it seems)).
At first I had tried to pass "this" to the bind function in function<void()>*AFunctionConstructor::constructFunction(CallerTypeFunc func)
,though, which i now get through the dynamic upcast.
Additionally the functionality of AFunctionConstructor was first supposed to be implemented in a Constructor of A.
This code gives me error in VS2015 update 1:
error C2893: Failed to specialize function template 'unknown-type
std::invoke(_Callable &&,_Types &&...)'
#include <iostream>
#include <functional>
using std::cout;
class A
{
public:
virtual void init()
{
cout << "A";
};
};
class B
{
public:
virtual void init()
{
cout << "B";
};
};
class C : private A, private B
{
std::function<void()> a_init = &A::init;
std::function<void()> b_init = &B::init;
public:
void call()
{
a_init();
b_init();
}
};
int main()
{
C c;
c.call();
return 0;
}
Any ideas if that's VS compiler is buggy or my code?
EDIT
#include "stdafx.h"
#include <functional>
class A
{
public:
virtual void inita()
{
cout << "A";
};
};
class B
{
public:
virtual void initb()
{
cout << "B";
};
};
class C : private virtual A, private virtual B
{
/*std::function<void()> a_init = &A::init;
std::function<void()> b_init = &B::init;*/
public:
void call()
{
inita();
}
};
You're trying to assign non-static member functions into a std::function taking no arguments. That cannot work, since non-static member functions have an implicit this parameter.
How to solve this depends on what you want to do. If you want to call the stored function on an arbitrary object supplied at call time, you'll need to change the std::function signature:
std::function<void(A*)> a_init = &A::init;
void call()
{
a_init(this); // or some other object of type A on which you want to invoke it
}
[Live example]
If, on the other hand, you want to call it without arguments, you will have to bind an object of type A into the std::function at initialisation:
std::function<void()> a_init = std::bind(&A::init, this);
void call()
{
a_init()
};
[Live example]
Change the function from virtual to static and the code will work. You need a specific instance of a class to call a non-static function.
On the other hand, if you wish to use non-static function, you can add the following constructor:
C(A &a, B &b)
{
a_init = std::bind(&A::init, &a);
b_init = std::bind(&B::init, &b);
}
and then use it in main like this:
A a;
B b;
C c(a, b);
c.call();
EDIT:
If public inheritance is acceptable option, then you can do it even simpler.
Constructor:
C()
{
a_init = std::bind(&A::init, this);
b_init = std::bind(&B::init, this);
}
Usage:
C c;
c.call();
If I have two classes:
class A{
f();
}
class B{
f();
};
I need to assign one of these classes to an object based on a condition like:
define variable
if condition1
variable = A
else
variable = B
and then I would use the assigned variable.f();
You should look toward inheritance and virtual functions.
Code might look like
class Base
{
virtual void f() = 0;
};
class A : public Base
{
virtual void f()
{
//class A realization of f
}
};
class B : public Base
{
virtual void f()
{
//class B realization of f
}
};
And then you can do this
Base* VARIABLE = 0;
if (*condition*)
{
VARIABLE = new A();
}
else
{
VARIABLE = new B();
}
VARIABLE->f();
But it not always a good idea to use inheritance and virtual functions. Your classes A and B should have something in common, at least the meaning of function f().
Provided A and B are meant to be unrelated types (i.e. not part of an inheritance hierarchy), you could use Boost.Variant in combination with the boost::static_visitor<> class to achieve something similar:
#include <boost/variant.hpp>
#include <iostream>
struct A { void f() { std::cout << "A::f();" << std::endl; } };
struct B { void f() { std::cout << "B::f();" << std::endl; } };
struct f_caller : boost::static_visitor<void>
{
template<typename T>
void operator () (T& t)
{
t.f();
}
};
bool evaluate_condition()
{
// Just an example, some meaningful computation should go here...
return true;
}
int main()
{
boost::variant<A, B> v;
if (evaluate_condition())
{
A a;
v = a;
}
else
{
B b;
v = b;
}
f_caller fc;
v.apply_visitor(fc);
}
What you are doing is known in design patterns as the "Factory Pattern". The above answers cover how it should be implemented. You can get more information at How to implement the factory method pattern in C++ correctly and wiki (http://en.wikipedia.org/wiki/Factory_method_pattern).
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) {}
};