I've got a class template in which I want to pass a function as an argument to another member function
MyClass.h:
template<typename CT>
class MyClass {
public:
double linfun(double x) { return 0.5 * x + 3.; }
virtual double some_method();
virtual double solver(std::function<double(double)> f, double k);
}
MyClass.cpp:
template<typename CT>
double MyClass<CT>::some_method() {
// do some calculations ...
x = 42.;
// Call solver function with linfun as argument:
return solver(linfun, x);
}
template<typename CT>
double MyClass<CT>::solver(std::function<double(double)> f, double k) {
return f(k);
}
This gives me the error:
nonstandard form for taking the address of a member function
return solver(linfun, x);
^
no suitable constructor exists to convert from "double (double)" to "std::function<double (double)>"
return solver(linfun, x);
^
detected during instantiation of "void MyClass<CT>::some_method() [with CT=SomeClassType]" at line 1234 of "SomethingElse.C"
I tried all proposed solutions I found, f.i.:
return solver(this->*linfun, x);
-> Same error
Next with this:
return solver(this->linfun, x);
With the following error:
error: a pointer to a bound function may only be used to call the function
return solver(this->linfun, x);
^
Any idea how to make this possible? I'm not restricted to using std::function
, but I'd prefer so.
You can't call a non-static member function without an object, so you can't just convert it to a std::function
.
There are several other suggestions you could use.
Make the function static
or a free function (the "minimal change" option - the function uses no class members).
Use a lambda object (the "modern" option when you need a non-static member).
return solver([this](double y) { return linfun(y); } , x);
template<typename CT>
class MyClass {
public:
double linfun(double x) { return 0.5 * x + 3.; }
virtual double some_method();
double solver(double (MyClass::*)(double) f, double k) { return this->*f(k); };
// ...
template<typename CT>
double MyClass<CT>::some_method() {
// do some calculations ...
x = 42.;
// Call solver function with linfun as argument:
return solver(&linfun, x);
}