Dereferencing pointer to functor inside a dereferenced class - c++

I have a functor like this
struct foo
{
int a;
foo(a) : a(a) {}
int operator()(int b) { return a+b; }
};
And a class like this
class bar
{
public:
foo* my_ftor;
bar(foo* my_ftor) : my_ftor(my_ftor) {}
~bar() {}
};
Then suppose a pointer to this class, which contains a pointer to foo.
foo MyFoo(20);
bar MyBar(&MyFoo);
In a function I pass a reference to bar, and I want to run the functor. I got it working the following way:
void AnyFunction(bar* RefToBar)
{
int y;
y = RefToBar->my_ftor->operator()(25);
}
Is there any other "cleaner" way to dereference the functor? Something akin to
y = RefToBar->my_ftor(25);
won't work, sadly...
Any idea? Thank you

Use real references:
class bar {
public:
foo &my_ftor;
bar (foo &f) : my_ftor(f) {}
};
void AnyFunction (bar &reftobar) {
int y = reftobar.my_ftor(25);
}
And call like this
foo myFoo(20);
bar myBar (myFoo);
AnyFunction (myBar);
In the interest of completeness, here is another answer that is more of a modern approach.
class foo {
public:
foo (int i) : a(i) {}
int operator() (int x) const {
return x + a;
}
private:
int a;
};
template <typename F>
void AnyFunction (const F &func) {
int y = func(25);
}
So you can pass in a foo directly:
AnyFunction (foo (20));
Or another kind of function object, like a lambda:
AnyFunction([](int x) -> int {
return x + 20;
});
You could also extend bar to include the following function:
int run_foo (int x) const {
return my_ftor (x);
}
And bind it (#include <functional>):
AnyFunction (std::bind (&bar::run_foo, &myBar, std::placeholders::_1));

Use std::function they are designed to hold functor of any sort.
#include <functional>
#include <iostream>
struct foo
{
int _a;
foo(int a) : _a(a) {}
int operator()(int b) { return _a+b; }
};
class bar
{
public:
std::function<int (int)> _ftor;
bar(std::function<int (int)> my_ftor) : _ftor(my_ftor) {}
~bar() {}
};
void AnyFunction(bar& RefToBar)
{
int y = RefToBar._ftor(25);
std::cout << "Y: " << y << std::endl;
}
int AnotherFunction(int b)
{
return b + 11;
}
int main(int argc, char const *argv[])
{
foo MyFoo(20);
bar MyBar(MyFoo);
bar MyBar_2(AnotherFunction);
bar MyBar_3([](int b) { return b + 56; });
AnyFunction(MyBar);
AnyFunction(MyBar_2);
AnyFunction(MyBar_3);
return 0;
}
http://ideone.com/K3QRRV

y = (*RefToBar->my_ftor)(25);
(better use std::function and don't violate demeter)

Related

How the base class calls the closure passed by the derived class in c++?

I have a base class, and it have a member function that sometime will be called. Usually, this function have a parameter that pointing to itself.
class Base {
public:
std::function<bool(Base *, int)> foo;
private:
int x{};
public:
static std::shared_ptr<Base> create() {
return std::make_shared<Base>();
}
Base() = default;
const std::function<bool(Base *, int)> &getFoo() const {
return foo;
}
void setFoo(const std::function<bool(Base *, int)> &foo) {
Base::foo = foo;
}
int getX() const {
return x;
}
void setX(int x) {
Base::x = x;
}
};
But when I have a derived class, how can I set this member function? Although the base class pointer can point to a subclass object, but I directly passed into the derived object, the compiler does not pass.
class Derived : public Base {
public:
static std::shared_ptr<Derived> create() {
return std::make_shared<Derived>();
}
};
int main() {
auto d = Derived::create();
d->setX(77);
d->setFoo([](Derived *derived, int x) -> bool { return derived->getX() > x; });
if (d->getFoo()) {
auto res = d->foo(d.get(), 99);
std::cout << res << std::endl;
}
return 0;
}
error: no viable conversion from '(lambda at
main.cpp:62:15)' to 'const
std::function'
b->setFoo([](Derived *derived, int x) -> bool { return derived->getX() > x; });
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So, is there any good idea to pass a closure to base class, and base class call it instead of derived class, and the most important thing is that closure have a parameter which is point to who pass the closure!
Note
I am going to assume that for some reason the closure in question needs access to Derived's methods/data members, and the OP's example does not convey that very well. Otherwise, why not just use Base * as the input parameter:
b->setFoo([](Base *derived, int x) -> bool { return derived->getX() > x; });
#user3655463's answer contains the full code for this case.
Simple solution
In case the CRTP solution proposed by #Yuki does not work for you, you could just use Base * as an argument of the closure and static_cast it in the closure body (the compiler can optimize away the cast), like this:
int main() {
auto d = Derived::create();
d->setX(77);
d->setFoo([](Base *derived, int x) -> bool {
return static_cast<Derived *>(derived)->getX() > x;
});
if (d->getFoo()) {
auto res = d->foo(d.get(), 99);
std::cout << res << std::endl;
}
return 0;
}
Live example.
If you really need the type in the closure to be Derived *
In case having Base * in the closure is not acceptable, you could hide the setFoo method from Base with a special implementation in Derived which will do the cast for you:
class Derived : public Base {
public:
static std::shared_ptr<Derived> create() {
return std::make_shared<Derived>();
}
template <typename Closure>
void setFoo(Closure foo) {
Base::setFoo([foo](Base *base, int x) {
return foo(static_cast<Derived *>(base), x);
});
}
};
int main() {
auto d = Derived::create();
d->setX(77);
d->setFoo([](Derived *derived, int x) -> bool {
return derived->getX() > x;
});
if (d->getFoo()) {
auto res = d->foo(d.get(), 99);
std::cout << res << std::endl;
}
return 0;
}
This allows you to use the same interface as you have in your original main funciton.
Live example.
If you have a lot of derived classes, and don't want to hide that method over and over again in each class
Now things get a bit complicated, and note that it's a good chance doing something like this would be overengineering in your case, but I just want to demonstrate that it can be done - here is where CRTP comes into play. It is used to implement a mixin which provides an implementation of the setFoo method:
template <typename ConcreteDerived, typename DirectBase>
class EnableSetFooAndInherit : public DirectBase {
public:
template <typename Closure>
void setFoo(Closure foo) {
DirectBase::setFoo([foo](DirectBase *base, int x) {
return foo(static_cast<ConcreteDerived *>(base), x);
});
}
};
class Derived : public EnableSetFooAndInherit<Derived, Base> {
public:
static std::shared_ptr<Derived> create() {
return std::make_shared<Derived>();
}
};
class Derived2 : public EnableSetFooAndInherit<Derived2, Base> {
public:
static std::shared_ptr<Derived2> create() {
return std::make_shared<Derived2>();
}
};
int main() {
auto d = Derived::create();
d->setX(77);
d->setFoo([](Derived *derived, int x) -> bool {
return derived->getX() > x;
});
if (d->getFoo()) {
auto res = d->foo(d.get(), 99);
std::cout << res << std::endl;
}
auto d2 = Derived2::create();
d2->setX(77);
d2->setFoo([](Derived2 *derived, int x) -> bool {
return derived->getX() < x;
});
if (d2->getFoo()) {
auto res = d2->foo(d.get(), 99);
std::cout << res << std::endl;
}
return 0;
}
Live example.
If a template base solution fits your style then this might work.
template <typename D>
class Base {
public:
std::function<bool(D*, int)> foo;
private:
int x{};
public:
static std::shared_ptr<Base> create() { return std::make_shared<Base>(); }
Base() = default;
const std::function<bool(D*, int)>& getFoo() const { return foo; }
void setFoo(const std::function<bool(D*, int)>& foo) { Base::foo = foo; }
int getX() const { return x; }
void setX(int x) { Base::x = x; }
};
class Derived : public Base<Derived> {
public:
static std::shared_ptr<Derived> create() { return std::make_shared<Derived>(); }
};
int main() {
auto d = Derived::create();
d->setX(77);
d->setFoo([](Derived* derived, int x) -> bool { return derived->getX() > x; });
if (d->getFoo()) {
auto res = d->foo(d.get(), 99);
std::cout << res << std::endl;
}
return 0;
}
Can't you just use Base (just as you designed):
d->setFoo([](Base* derived, int x) -> bool { return derived->getX() > x; });
Whole code:
#include <algorithm>
#include <iostream>
#include <vector>
#include <functional>
#include <memory>
class Base {
public:
std::function<bool(Base *, int)> foo;
private:
int x{};
public:
static std::shared_ptr<Base> create() {
return std::make_shared<Base>();
}
Base() = default;
const std::function<bool(Base *, int)> &getFoo() const {
return foo;
}
void setFoo(const std::function<bool(Base *, int)> &foo) {
Base::foo = foo;
}
int getX() const {
return x;
}
void setX(int x) {
Base::x = x;
}
};
class Derived : public Base {
public:
static std::shared_ptr<Derived> create() {
return std::make_shared<Derived>();
}
};
int main() {
auto d = Derived::create();
d->setX(77);
d->setFoo([](Base* derived, int x) -> bool { return derived->getX() > x; });
if (d->getFoo()) {
auto res = d->foo(d.get(), 99);
std::cout << res << std::endl;
}
return 0;
}

Avoid the class scope so as to pass a member function as a function pointer

I'll describe my question using the following sample code.
I have class B defined as follows:
class B
{
public:
inline B(){}
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(int (*f)(int x)) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
int(*myfunc)(int);
};
I then define class A as follows:
class A
{
public:
A(int myint) :a{ myint }{ b.setfunction(g); }
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
To me the issue seems to be that the member function g has the signature int A::g(int) rather than int g(int).
Is there a standard way to make the above work? I guess this is quite a general setup, in that we have a class (class B) that contains some sort of member functions that perform some operations, and we have a class (class A) that needs to use a particular member function of class B -- so is it that my design is wrong, and if so whats the best way to express this idea?
You can use std::function:
class B
{
public:
inline B() {}
inline B(std::function<int(int)> f) : myfunc{ f } {}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction([this](int a) {
return g(a);
}
);
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
You could generalize the class B. Instead of keeping a pointer (int(*)(int)), what you really want is any thing that I can call with an int and get back another int. C++11 introduced a type-erased function objection for exactly this reason: std::function<int(int)>:
class B
{
using F = std::function<int(int)>
public:
B(){}
B(F f) : myfunc(std::move(f)) { }
void setfunction(F f) { myfunc = std::move(f); }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
F myfunc;
};
And then you can just provide a general callable into B from A:
A(int myint)
: b([this](int a){ return g(a); })
, a{ myint }
{ }
Use std::function and std::bind
class B
{
public:
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
// ...
A a;
B b(std::bind(&A::g, &a));
Also note that you should initialize the function pointer to some default value (most likely null) and check for it when using, otherwise it's value is undefined.
You could use std::bind to bind the member function A::g.
class B
{
public:
inline B(){}
inline B(std::function<int(int)> f) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction(std::bind(&A::g, this, std::placeholders::_1));
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
Note you need to change the type of functor from function pointer to std::function, which is applicable with std::bind.
LIVE

Can I give function pointer to template parameter?

Can I do something like this?
template<function_pointer_type pointer_name> struct structure1{
//here I call pointer_name(0)
};
void* function1 = [&](int a) {
return a * a;
}
structure1<function1> b;
I tried but it never compiled.
So, what's wrong with the code?
function1 is not constant expression so it cannot be used as template argument.
The lambda is not convertible to function pointer because it has a non-empty capture list.
Instead of function pointer, I suggest using a template parameter of function object, or std::function.
Function object:
template <class FunctionObject>
class A
{
private:
FunctionObject fun;
public:
A(FunctionObject f) : fun(f) {}
void f() { cout << fun(5) << endl; }
};
template <class FunctionObject>
A<FunctionObject> make_A(FunctionObject f)
{
return A<FunctionObject>(f);
}
std::function:
template <class FunctionType>
struct B
{
std::function<FunctionType> fun;
};
The usage:
void usage()
{
auto a = make_A([](int a) {return a*a; });
a.f();
B<int(int)> b;
b.fun = [&](int a) {return a*a; };
cout << b.fun(10) << endl;
}
To make this as absolutely similar to your original question as possible (using a lambda and a templated structure and so on):
#include <iostream>
template<typename F>
struct structure1 {
structure1(F x) : f(x) {}
int operator() (int a) { return f(a); };
F f;
};
int(*function1)(int) = [&](int a) {
return a * a;
};
int main() {
structure1< int(*)(int) > x(function1);
std::cout << x(4) << std::endl;
return 0;
}
I compiled and tested this with g++ -std=c++11 test.cpp

Pointer to a member-function

I would like to do the following:
I have two classes, A and B, and want to bind a function from A to a function from B so that whenever something calls the function in B, the function from A is called.
So basically, this is the scenario:
(important A and B should be independent classes)
This would be class A:
class A {
private:
// some needed variables for "doStuff"
public:
void doStuff(int param1, float *param2);
}
This is class B
class B {
private:
void callTheFunction();
public:
void setTheFunction();
}
And this is how I would like to work with these classes:
B *b = new B();
A *a = new A();
b->setTheFunction(a->doStuff); // obviously not working :(
I've read that this could be achieved with std::function, how would this work? Also, does this have an impact in the performance whenever callTheFunction() is called? In my example, its a audio-callback function which should call the sample-generating function of another class.
Solution based on usage C++11 std::function and std::bind.
#include <functional>
#include <stdlib.h>
#include <iostream>
using functionType = std::function <void (int, float *)>;
class A
{
public:
void doStuff (int param1, float * param2)
{
std::cout << param1 << " " << (param2 ? * param2 : 0.0f) << std::endl;
};
};
class B
{
public:
void callTheFunction ()
{
function (i, f);
};
void setTheFunction (const functionType specificFunction)
{
function = specificFunction;
};
functionType function {};
int i {0};
float * f {nullptr};
};
int main (int argc, char * argv [])
{
using std::placeholders::_1;
using std::placeholders::_2;
A a;
B b;
b.setTheFunction (std::bind (& A::doStuff, & a, _1, _2) );
b.callTheFunction ();
b.i = 42;
b.f = new float {7.0f};
b.callTheFunction ();
delete b.f;
return EXIT_SUCCESS;
}
Compile:
$ g++ func.cpp -std=c++11 -o func
Output:
$ ./func
0 0
42 7
Here's a basic skeleton:
struct B
{
A * a_instance;
void (A::*a_method)(int, float *);
B() : a_instance(nullptr), a_method(nullptr) {}
void callTheFunction(int a, float * b)
{
if (a_instance && a_method)
{
(a_instance->*a_method)(a, b);
}
}
};
Usage:
A a;
B b;
b.a_instance = &a;
b.a_method = &A::doStuff;
b.callTheFunction(10, nullptr);
This i basic a solution
class A {
private:
// some needed variables for "doStuff"
public:
void doStuff(int param1, float *param2)
{
}
};
typedef void (A::*TMethodPtr)(int param1, float *param2);
class B {
private:
TMethodPtr m_pMethod;
A* m_Obj;
void callTheFunction()
{
float f;
(m_Obj->*m_pMethod)(10, &f);
}
public:
void setTheFunction(A* Obj, TMethodPtr pMethod)
{
m_pMethod = pMethod;
m_Obj = Obj;
}
};
void main()
{
B *b = new B();
A *a = new A();
b->setTheFunction(a, A::doStuff); // now work :)
}

<unresolved overloaded function type> when trying to pass an aggregated object's method to its class method

I have some problem compiling my code.
I have the following structure:
#include <cstdlib>
using namespace std;
typedef double (*FuncType)(int );
class AnotherClass {
public:
AnotherClass() {};
double funcAnother(int i) {return i*1.0;}
};
class MyClass {
public:
MyClass(AnotherClass & obj) { obj_ = &obj;};
void compute(FuncType foo);
void run();
protected:
AnotherClass * obj_; /*pointer to obj. of another class */
};
void MyClass::compute(FuncType foo)
{
int a=1;
double b;
b= foo(a);
}
void MyClass::run()
{
compute(obj_->funcAnother);
}
/*
*
*/
int main(int argc, char** argv) {
AnotherClass a;
MyClass b(a);
b.run();
return 0;
}
When I try to compile it, it gives:
main.cpp:39:31: error: no matching function for call to ‘MyClass::compute(<unresolved overloaded function type>)’
main.cpp:30:6: note: candidate is: void MyClass::compute(double (*)(int))
What's wrong here?
p/s/ AnotherClass * obj_; should stay like that because I write some function to the big library and can't change it.
-------------- working version by Benjamin -------
#include <cstdlib>
using namespace std;
class AnotherClass {
public:
AnotherClass() {};
double funcAnother(int i) {return i*1.0;}
};
struct Foo
{
/*constructor*/
Foo(AnotherClass & a) : a_(a) {};
double operator()(int i) const
{
return a_.funcAnother(i);
}
AnotherClass & a_;
};
class MyClass {
public:
MyClass(AnotherClass & obj) { obj_ = &obj;};
template<typename FuncType>
void compute(FuncType foo);
void run();
protected:
AnotherClass * obj_; /*pointer to obj. of another class */
};
template<typename FuncType>
void MyClass::compute(FuncType foo)
{
int a=1;
double b;
b= foo(a);
}
void MyClass::run()
{
Foo f(*obj_);
compute(f);
}
/*
*
*/
int main(int argc, char** argv) {
AnotherClass a;
MyClass b(a);
b.run();
return 0;
}
Thank you everybody very much for the help!
Since,
funcAnother(int i);
is a member function it passes an implicit this and then the prototype does not match the type of your function pointer.
The typedef for pointer to member function should be:
typedef double (AnotherClass::*funcPtr)(int);
Here is a modified compilable version of your code. Please check the comments inline to understand the changes, Also I left out the other details, you can add that up.
The following function class will match the signature of your FuncType:
struct Foo
{
AnotherClass & a_;
Foo(AnotherClass & a) a_(a) {}
double operator()(int i) const
{
return a_.funcAnother(i);
}
};
Change MyClass::compute to a template, thusly:
template<typename FuncType>
void MyClass::compute(FuncType foo)
{
int a=1;
foo(a);
}
Then you can call run like this:
void MyClass::run()
{
compute(Foo(*obj_));
}
If your compiler supports lambdas (and there's a good chance it does), then you can forgo the function class and simply define run like this:
void MyClass::run()
{
auto f = [this](int i) {
return obj_->funcAnother(i);
};
compute(f);
}