passing a pointer to a class method as a function argument [duplicate] - c++

This question already has answers here:
How do you pass a member function pointer?
(6 answers)
Closed 9 years ago.
I have a class
class A{
A(/*constructor arguments*/);
double MethA(double);
};
And I want to pass the method MethA in a function that takes a pointer to a function :
double function(double (*f)(double), double x){
return f(x);
}
So what I'm doing is to call
A a(/*constructor arguments*/);
function(a.MethA,1.0);
but it doesn't compile.
I'm pretty sure that this question is answered somewhere else, but I couldn't find where because I'm not sure that the terminology I use is correct. Am I trying to pass a pointer on a class method as a function argument ? Or, to pass a function pointer as a member of a class... I'm confused :-(

When you need to use a pointer to member function, you need to pass two separate things:
what member function to call and
what instance to call it on.
In C++, you can't combine them in one construct, like you want to:
A a;
bar(a.foo);
is not valid C++.
Instead, you have to do this:
A a;
bar(a, &A::foo)
And declare and implement bar() accordingly:
void bar(A &a, void (A::*method)()) {
a.*method();
}

See Arkadiy's answer if you want to see how to properly use member function pointers.
BUT
As requested in the comments: if the compiler you are using supports lambdas (some without full C++11 do). You can do something like the following, which looks more like the syntax you are attempting to use.
Your definition for function changes to something like:
template <typename F>
double function(F f, double x){
return f(x);
};
a function template that accepts a parameter that is callable with a double.
At your call-site you do this:
A a(/*constructor arguments*/);
function([&](double x){return a.MethA(x);},1.0);
That generates a function object in-place that is bound to your class instance a by reference.
The template can be made fully typesafe with some magic in <type_traits>, but as-is it will give you template spew if you pass something very wrong.

It has to be a static function!
#include <iostream>
#include <cassert>
class A {
public:
static double MethA(double x) { return 5 * x; }
};
typedef double (*ftype)(double);
double function(ftype f) {
assert(f != NULL);
return f(7);
}
int main(int, char**) {
// expect "35\n" on stdout
std::cout << function(A::MethA) << "\n";
}
It has to be static because you can't access any of A's variables without knowing which A object are you refering to! If you need A's non-static member variables, you need to pass a reference to an a into the static function:
#include <iostream>
#include <cassert>
class A {
double fX;
public:
A(double x) : fX(x) { }
double methB(double x) const { return fX * x; }
static double MethB(double x, const A& a) {
return a.methB(x);
}
};
typedef double (*ftype2)(double, const A&);
double function_with_context(ftype2 f, const A& a) {
assert(f != NULL);
return f(7, a);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function_with_context(A::MethB, a) << "\n";
}
But it's sometimes better to use inheritance and polymorphism to achieve this sort of interface:
#include <iostream>
class MyInterface {
public:
virtual double f(double x) const = 0;
};
class A : public MyInterface {
double fX;
public:
A(double x) : fX(x) { }
double f(double x) const {
return fX * x;
}
};
double function(const MyInterface& o) {
return o.f(7);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function(a) << "\n";
}

Related

Call a class's function template with function pointers as parameters

I'd want to use a function pointer in my template argument list. I do miss something of B even I am writing int in full main of both A and B. I have a class X.h like so, don't know which one it is now causing the error.
struct X
{
int fun(int a)
{
return a;
}
template<typename A, typename B>
A func(int x, B(*f)(int))
{
A i = 10;
return i + f(x);
}
};
and I like to use it in main.cpp
int main()
{
X d;
std::cout << d.func<int, int>(10, &X::fun) << "\n";
return 0;
}
The error is No instance of func matches the argument list...
The problem is that the argument &X::fun is of type int (X::*)(int) while the parameter f is of type int(*)(int) (when B = int) and there is no implicit conversion from the former to the latter and hence the error.
To solve this you can change the parameter f to be of type B(X::*)(int) as shown below. Note that the syntax for making a call using member function pointer is different for making a call to a free function.
With C++17, we can use std::invoke.
struct X
{
int fun(int a)
{
return a;
}
template<typename A, typename B>
//------------------vvvv-------------->added this X:: here
A func(int x, B(X::*f)(int))
{
A i = 10;
//-----------------vvvvvvvvvv-------->this is the syntax to call using member function pointer
return i + (this->*f)(x);
//return std::invoke(f, this, x); //use std::invoke with C++17
}
};
int main()
{
X d;
std::cout << d.func<int, int>(10, &X::fun) << "\n"; //works now
return 0;
}
Working demo

Pass reference to external function in class constructor

There are other questions regarding how to pass an external function as an argument to a function in C++, but I am struggling to apply those answers to the case where the target function is the constructor function for a novel class.
Here is what I am trying to do:
#include <iostream>
double external_function(double x, double y) {
return x * y;
}
class foo {
public:
// Initialize a function (?) as a method of class foo
double func(double, double);
// Construct an instance of the class by supplying a pointer to an external function
foo(double(*func_in)(double, double)) {
func = *func_in;
}
// When calling this method, evaluate the external function
double eval(double x, double y) {
return func(x, y);
}
};
int main() {
foo foo_instance(&external_function);
std::cout << foo_instance.eval(1.5, 2); // Should print 3
return 0;
}
I would like to have func as a method of the foo class because I later will write methods of foo that do other things with func, e.g. search for a local minimum.
By analogy, here is working code that passes an external constant instead of a function:
#include <iostream>
double external_value = 1.234;
class bar {
public:
// Initialize a value as a method of class bar
double val;
// Construct an instance of the class by supplying a pointer to an external value
bar(double* val_in) {
val = *val_in;
}
// When calling this method, return the external function
double eval() {
return val;
}
};
int main() {
bar bar_instance(&external_value);
std::cout << bar_instance.eval(); // 1.234
return 0;
}
Like this
class foo {
public:
// Initialize a function pointer as a method of class foo
double (*func)(double, double);
// Construct an instance of the class by supplying a pointer to an external function
foo(double(*func_in)(double, double)) {
func = func_in;
}
// When calling this method, evaluate the external function
double eval(double x, double y) {
return func(x, y);
}
};
In your version func was an undefined method of the class not the function pointer you wanted it to be.
Here is the example using std::function:
#include <functional>
class foo {
public:
// Initialize a function as a method of class foo
std::function<double(double, double)> func;
// Construct an instance of the class by supplying a pointer to an external function
foo(std::function<double(double, double)> func_in) {
func = func_in;
}
// When calling this method, evaluate the external function
double eval(double x, double y) {
return func(x, y);
}
};

Using a custom constructor as a template function

I have template function change that takes a function that takes int and returns an object of type A. So I thought I can use the constructor of A
class A {
int y;
public:
explicit A(int y) : y(2 * y) {
}
};
class B {
A x;
public:
B(int x) : x(x) {
}
template<typename F>
void change(int y, F func) {
x = func(y);
}
};
int main(void) {
B b(7);
b.change(88, A()); // << here
return 0;
}
But the compiler says no matching function for call to ‘A::A()’
How can I make it works?
You can't pass a constructor as a parameter like you are attempting. The C++ standard is very strict on not allowing the memory address of a constructor to be taken.
When you call change(88, A()), you are actually constructing a temp A object (which the compiler should not allow since A does not have a default constructor) and then you are passing that object to the parameter of change(). The compiler is correct to complain, since A does not define an operator()(int) to satisfy the call to func(y) when called in an A object.
To make this work, you need to create a separate function that constructs the A object, and then pass that function to change(), eg:
A createA(int y)
{
return A(y);
}
int main(void) {
B b(7);
b.change(88, createA);
return 0;
}

How to create a new function from a method, with fewer arguments?

I have two classes, ClassA and ClassB.
ClassA has three methods:
double Foo(double, ClassB);
double Bar(double (*f)(double));
double Baz(double, ClassB);
I would like to define a function Qux inside Foo, based on Baz but without the argument of type ClassB: i.e. of the kind "double Qux(double)" so that I can pass it to Bar:
double ClassA::Foo(double x, ClassB y)
{
// double Qux(double .) = Baz(., y)
Bar((*Qux))
}
Does some one have any idea?
I guess some will answer this is not the good way to do it. So just to explain the concrete situation, I am pricing financial assets using a numerical method (http://en.wikipedia.org/wiki/Simpson%27s_rule) in order to compute integrals:
ClassA: FinancialAsset
ClassB: PrincingModel
Foo: FinancialAsset.Price(date, PrincingModel)
Bar: FinancialAsset.SimpsonMethod(FunctionOneArgument)
Baz: FinancialAsset.FunctionTwoArguments(date, PrincingModel)
And I am looking for:
Qux: FunctionOneArgument(date) = FinancialAsset.FunctionTwoArguments(date, PrincingModel)
I am not sure what is the good way to address this structure. I you have a better / more c++'s way to do it, I'll take :)
Thanks
You can't do that exactly, because your Bar function is taking a pointer to a regular function, but you can use this instead:
class A {
...
public:
double Foo(double, ClassB);
double Bar(std::function<double(double)> f);
double Baz(double, ClassB);
};
double ClassA::Foo(double x, ClassB y)
{
auto Qux = [&](double x) { Baz(x,y); };
return Bar(Qux);
}
std::function is a more general way of representing function-like objects. You can convert a regular function, a lambda, or a function object to it.
Depending on whether you have C++11 or not, you either want std::bind and std::function or boost::bind and boost::function for older C++ versions.
binding allows you to take a function and bind 0 or more of the parameters, or rearrange the parameters. Indeed something you have above would look like this:
double ClassA::Foo(double x, ClassB y)
{
boost::function<double> baz = boost::bind(this, ClassA::Baz, _1, y);
Bar(baz);
}
And Bar's signature would take a boost::function instead of a function pointer.
Note my syntax might be slightly off for binding memeber functions, have a look at the documentation for details.
see here:
http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html
Or here: http://en.cppreference.com/w/cpp/utility/functional/bind
You can do it without changing any function signatures (and C++11 or boost), but I wouldn't suggest it if you can avoid it. It's ugly, not thread-safe, and in general not very nice:
#include <iostream>
struct B
{
// some data in B
int i;
};
struct A
{
//some data in A
double d;
// the functions you defined in A
double Foo(double x, B y);
double Bar(double (*f)(double));
double Baz(double x, B y);
};
// a poor substitutes for closures
struct
{
A *a;
B *b;
} hack;
double Qux(double x2)
{
// use the stored pointer to call Baz on x2
return hack.a->Baz(x2, *hack.b);
}
double A::Foo(double x, B y)
{
// store pointers for use in Qux
hack.a = this;
hack.b = &y;
// do something with x
d += x;
double result = Bar(&Qux);
return result;
}
double A::Bar(double (*f)(double))
{
// do something with d, call the passed function
d += 1;
return f(d);
}
double A::Baz(double x, B y)
{
// do something with the passed data
return x + y.i;
}
int main()
{
A a;
a.d = 1.25;
B b;
b.i = 2;
std::cout << a.Foo(.25, b) << std::endl; // should be 4.5
return 0;
}

Dynamically create a function pointer that calls a method on a given instance

I suspect this is impossible, but thought I'd ask. Say I have a class with a method:
class A {
public:
void b(int c);
};
I can make a pointer to that member function:
void (A::*ptr)(int) = &A::b;
(someAInstance.*ptr)(123);
I can also abuse function pointers and make a pointer that takes the A argument directly (I don't know if this is safe, but it works on my machine):
void (*ptr2)(A*, int) = (void (*)(A*, int))&A::b;
(*ptr2)(&someAInstance, 123);
What I want is to somehow curry the A argument, and create a function pointer that just takes an int, but calls the A::b method on a particular A instance I've predefined. The A instance will stay constant for that particular function pointer, but there may be several function pointers all pointing to the same A::b method, but using different A instances. For example, I could make a separate wrapper function:
A* someConstantA = new A;
void wrapper(int c) {
someConstantA->b(c);
}
void (*ptr3)(int) = &wrapper;
Now I can use ptr3 without knowing which particular A it's dispatching the call to, but I had to define a special function to handle it. I need a way to make pointers for any number of A instances, so I can't hardcode it like that. Is this in any way possible?
Edit: Should've mentioned, I'm trapped in C++03 land, and also can't use Boost
Don't create a wrapper function, create a wrapper functor. This allows you to encapsulate whatever state you want to (e.g. an A*) in a callable object.
class A {
public:
void b(int c) {}
};
struct wrapper {
A* pA;
void (A::*pF)(int);
void operator()(int c) { (pA->*pF)(c); }
wrapper(A* pA, void(A::*pF)(int)) : pA(pA), pF(pF) {}
};
int main () {
A a1;
A a2;
wrapper w1(&a1, &A::b);
wrapper w2(&a2, &A::b);
w1(3);
w2(7);
}
If you have a sufficiently new compiler (e.g. gcc 4.2+), it should include TR1, where you could use std::tr1::bind:
#include <cstdio>
#include <tr1/functional>
class A {
public:
void b(int c) {
printf("%p, %d\n", (void*)this, c);
}
};
int main() {
A* a = new A;
std::tr1::function<void(int)> f =
std::tr1::bind(&A::b, a, std::tr1::placeholders::_1); // <--
f(4);
delete a;
return 0;
}
It is also doable in pure C++03 without TR1, but also much more messier:
std::binder1st<std::mem_fun1_t<void, A, int> > f =
std::bind1st(std::mem_fun(&A::b), a);
You could also write your own function objects.
Note that, in all the above cases, you need to be very careful about the lifetime of a since that is a bare pointer. With std::tr1::bind, you could at least wrap the pointer in a std::tr1::shared_ptr, so that it can live just as long as the function object.
std::tr1::shared_ptr<A> a (new A);
std::tr1::function<void(int)> f =
std::tr1::bind(&A::b, a, std::tr1::placeholders::_1);
If you are using C++11, you might use a lambda (untested code):
template<typename T, typename A>
std::function<void(A)> curry(T& object, void (T::*ptr)(A))
{
return [](A a) { (object.*ptr)(std::forward<A>(a)); }
}
I'd be using Boost::bind for this.
Basically:
class A
{
int myMethod(int x)
{
return x*x;
}
};
int main(int argc, char* argv[])
{
A test();
auto callable = boost::bind(&A::myMethod, &A, _1);
// These two lines are equivalent:
cout << "object with 5 is: " << test.myMethod(5) << endl;
cout << "callable with 5 is: " << callable(5) << endl;
return 0;
}
I think that should work. I'm also using auto in here to deduce the type returned by boost::bind() at compile-time, which your compiler may or may not support. See this other question at stackoverflow for an explanation of the return type of bind.
Boost supports back to Visual Studio 2003 (I think) and this all this will work there, though you'll be using BOOST_AUTO I think. See the other question already linked for an explanation.
What you want to do is not possible.
To see why, assume that it is possible - the function pointer must point to a function somewhere in your executable or one of its libraries, so it must point to a function that knows which instance of A to call, much like your wrapper function. Because the instance of A is not known until runtime, you'd have to create those functions at runtime, which isn't possible.
What you're trying to do is possible in C++03, as long as you're happy to pass around a function object rather than a function pointer.
As others have already given solutions with C++11 lambdas, TR1 and boost (all of which are prettier than the below), but you mentioned you can't use C++11, I'll contribute one in pure C++03:
int main()
{
void (A::*ptr)(int) = &A::b;
A someAInstance;
std::binder1st<std::mem_fun1_t<void,A,int> > fnObj =
std::bind1st(std::mem_fun(ptr), &someAInstance);
fnObj(321);
};
I've worked something out with a template Delegate class.
// T is class, R is type of return value, P is type of function parameter
template <class T, class R, class P> class Delegate
{
typedef R (T::*DelegateFn)(P);
private:
DelegateFn func;
public:
Delegate(DelegateFn func)
{
this->func = func;
}
R Invoke(T * object, P v)
{
return ((object)->*(func))(v);
}
};
class A {
private:
int factor;
public:
A(int f) { factor = f; }
int B(int v) { return v * factor; }
};
int _tmain(int argc, _TCHAR* argv[])
{
A * a1 = new A(2);
A * a2 = new A(3);
Delegate<A, int, int> mydelegate(&A::B);
// Invoke a1->B
printf("Result: %d\n", mydelegate.Invoke(a1, 555));
// Invoke a2->B
printf("Result: %d\n", mydelegate.Invoke(a2, 555));
_getch();
delete a1;
delete a2;
return 0;
}