3

Fairly new to C++. Suppose I have a class:

class A
{
private:
    double m_x, m_y;
public:
    A(double x, double y): m_x {x}
    {
        m_y = extF(m_x, y, *intF);
    }

    double intF(double x) { return 2*x; }
};

And it makes use of an external global function, defined elsewhere:

double extF(double x, double y, std::function<double(double)> f)
{
    if (x*y < 0)
        return f(x);
    else
        return f(y);
}

Formulas are bogus. This does not compile. I tried simple intF, A::*intF, &A::intF, even some unorthodox combinations, but that's just guessing. The problem is that class A is not the only one which makes use of the global external function and it's something that should be able to be a user choice at runtime. Searches revealed some answers saying it's not possible to make a pointer to a member function like this because it needs instantiation(?), but I found no solutions. Can this be done? If yes, how?


Edit: Additional question: how can the pointer to member function be done if the member function is const double f(...) const?

3
  • Make intF static member function if it won't access any members of the class. Commented Aug 20, 2016 at 12:03
  • @songyuanyao Unfortunately, it does. If I knew this was a problem, I would have modified the code to show. Commented Aug 20, 2016 at 12:05
  • @aconcernedcitizen Not your fault, but mine. I went OT first, lets delete these comments. Commented Aug 20, 2016 at 12:54

2 Answers 2

3

One variant is just to use lambda:

class A
{
private:
    double m_x, m_y;
public:
    A(double x, double y): m_x {x}
    {
         m_y = extF(m_x, y, [&](double d){ return intF(d);});
    }

    double intF(double x) { return 2*x; }
};

Another variant is to use lambda and std::mem_fn (omitting the rest code of your class):

A(double x, double y): m_x {x}
{
    auto fn = std::mem_fn(&A::intF);
    m_y = extF(m_x, y, [&](double d) {return fn(this, d);});
}

And finally you may get rid of lambdas if you bind the object parameter of member function pointer:

A(double x, double y): m_x {x}
{
    auto fn1 = std::bind(std::mem_fn(&A::intF), this, std::placeholders::_1);
    m_y = extF(m_x, y, fn1);
}

All these also work with constant member functions.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, both (@songuyanyao and you), for your answers. I don't know about the std::mem_fn and std::bind yet. I'll read about them now.
2

You could use std::bind to bind the member function.

A(double x, double y): m_x {x}
{
    using namespace std::placeholders;
    m_y = extF(m_x, y, std::bind(&A::intF, this, _1));
}

Or use a lambda.

A(double x, double y): m_x {x}
{
    m_y = extF(m_x, y, [this](double d) { return intF(d); });
}

BTW: It works well with const member function too, which doesn't matter here.

LIVE

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.