Solved Must call pointer-to-member function in dlib but can't figure out the syntax ;(
-
Hi!
I have to solve some pretty heavy math problems.
For that I want to use the power of http://dlib.net/This is one of the functions I want to implement:
template < typename funct > double find_min_single_variable ( const funct& f, double& starting_point, const double begin = -1e200, const double end = 1e200, const double eps = 1e-3, const long max_iter = 100, const double initial_search_radius = 1 )
I can do this as long as "funct" is static, but "funct" has to utilize other class members in the future, so as far as I know it can't be static.
#include <dlib/optimization.h> class DlibTest { public: // f(x) will use this in the future qreal someVariable; // Find the minimum of f(x) qreal findMin(qreal x0) { someVariable = 123.; // This only works, because "f" is static // Otherwise the compiler throws: must use '.*' or '->*' to call pointer-to-member function return dlib::find_min_single_variable(f,x0); } // Implementation of f(x) static qreal f(qreal x) { // This function has to use "someVariable" in the future return qSqrt(qPow(x*8,2))+5; } };
There is plenty of helpful advice on the Internet (e.g. https://isocpp.org/wiki/faq/pointers-to-members#typedef-for-ptr-to-memfn) but no matter what I do, I get "must use '.' or '->' to call pointer-to-member function" or the compiler complains about "too few arguments for f()".
This has to be a (simple?) syntax confusion, because as I said: calling a static function works like a charm.
Please help :)
Kind regards,
Mr.Floppy.
EDIT:
Just to clearify what I mean:
The code below throws "too few arguments to function", but I can't provide arguments. Dlib will do that.
If I do "(this->*pmf)(x0)" it says "expression cannot be used as a function".
I am so confused right now...// dlibtest.h #include <QObject> #include <QtMath> #include <dlib/optimization.h> class DlibTest { public: DlibTest(); typedef qreal (DlibTest::*DlibTestMemFn)(qreal x); DlibTestMemFn pmf; qreal findMin(qreal x0); qreal f(qreal x); }; // dlibtest.cpp #include "dlibtest.h" DlibTest::DlibTest() { findMin(3); } qreal DlibTest::findMin(qreal x0) { pmf = &DlibTest::f; return dlib::find_min_single_variable((this->*pmf)(),x0); } qreal DlibTest::f(qreal x) { return qSqrt(qPow(x*8,2))+5; } // Throws: too few arguments to function f()
-
@Mr.Floppy I never used dlib, so don't know whether this work: did you try to use a functor (a class with operator()())?
-
@jsulm
Thanks for the reply. Never have I ever used functors, but what I have read about them so far doesn't seem too helpful with my current problem.
I will read some more, but do you already have an idea how it could work?Anyway, I think my problem is not that dlib-specific.
Basically I just have a function in the dlib namespace that is declared like this:
template <typename funct> double science_stuff (const funct& f);
And I have a math problem which is a member of my object:
double f(double x);
"science_stuff" is now supposed to solve my math problem "f" by iterating over it with different values for "x".
What I am struggling with is casting "f" so it suits the "const funct& f" argument.
-
@Mr.Floppy You cannot do this with a non-static member function. The problem is: the member function needs the pointer to the object it's going to operate on (the this pointer). See https://isocpp.org/wiki/faq/pointers-to-members
Functor:
class Functor { public: void operator()(/* parameters */) { // Do something } } ... Functor f; science_stuff(f);
-
@jsulm
THANK YOU!I can't say that I fully understand why it works, but at least now I know how to use it :)
A Functor is indeed the way to solve my problem without the need of a member function, because I can pass constants as an argument :)This is it.
Of course the "math-problem" is complete nonsense but it is super easy to verify ;)Thanks again for the quick help!!
// dlibtest.h #include <QObject> #include <QtMath> #include <dlib/optimization.h> class mathProblem { public: mathProblem (const qreal& yIn, const qreal& zIn) { y = yIn; z = zIn; } double operator() ( const qreal& x) const { return y*qSqrt(qPow(x,2))+z; } private: qreal y; qreal z; }; class DlibTest { public: DlibTest(); qreal findMin(qreal x0); }; // dlibtest.cpp #include "dlibtest.h" #include <QDebug> DlibTest::DlibTest() { qDebug() << findMin(0); } qreal DlibTest::findMin(qreal x0) { return dlib::find_min_single_variable(mathProblem(2,3),x0); }
-
Glad I could help you :-)
-
Side note: if that is your math problem dlib is a bit overkill, boost::math does it and it's just an header, no linking
-
@VRonin
Of course the math problem is just a placeholder.
Honestly, I don't know the advantages of dlib or boost. A few days ago dlib seemed to me a bit more accessible.
In the meantime I stumbled across a problem that seems way more easily solved with boost. So as a matter of fact I already am using boost by now :)The implementation is almost the same for both libraries, and luckily the usage with functors is also the same.
Boost seems to need a little more groundwork than dlib, but that isn't necessarily a bad thing.