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()
    

  • Moderators

    @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.


  • Moderators

    @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);
    }
    

  • Moderators

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.