kz965
kz965

Reputation: 27

C++ to port member function from other classes

Suppose I have two different classes shown below

class Nonlinear
{
   public:
   double NonlinearFunc(ParameterList) //it is a nonlinear function 
};

class Solver
{
   public:
   double FuncEvaluation(ParameterList) //evaluate a function
};

double Solver::FuncEvaluation(ParameterList)
{
    ????? //evaluate function from other class
}

main()
{
    Nonlinear nl;
    Solver solve;
    double a;
    double b;
    a = nl.NonlinearFunc(ParameterList);
    b = solve.FuncEvaluation(ParameterList);

    //what I want is a=b
}

How do I use member function pointer so the Solver::FunEvaluation evaluates Nonlinear::NonlinearFunc?

Upvotes: 1

Views: 125

Answers (4)

Christophe
Christophe

Reputation: 73627

You want to call NonLinear::NonLinearFunc() from Solver::FuncEvaluation.

As your class Solver is not derived from class NonLinear, and as NonLinearFunc() is a member function of class NonLinear, you must have in FuncEvaluation an object (let's call it x) of class NonLinear, for example, one of the parameters.

If this is the case, you don't need a pointer to a member function, but just call the function:

 x.NonLinearFunc(...)   // or x->NonLinearFunc(...) if you work with pointers.   

A pointer to a member function would then only make sense, if you would have several similar member functions and would like to dynamically choose one.

Edit:

For using a pointer to a member function, when really necessary, do as follow:

double (NonLinear::*f)(...); // declare a pointer to a member function of Nonlinear
f = &A::NonLinearFunc;       // Assign the address of the function to the pointer.  Note the mandatory &    
(x.*f)(...);                 // call the function pointed to, using NonLinear object x with the given parameters

Note that in this example, the pointer f is not a member of NonLinear, but a variable with type "pointer to a member function of class NonLinear". It would be a variable of your solver.

Upvotes: 1

Felix Glas
Felix Glas

Reputation: 15524

To me it sounds like you want the function FuncEvaluation to be able to accept any (member) function as a parameter and evaluate it using its own parameters.

In modern C++ you can do something like this1:

struct Solver {
    template <typename Callable, typename... Args>
    auto funcEvaluation(Callable&& c, Args&&... args) {
        return std::forward<Callable>(c)(std::forward<Args>(args)...);
    }
};

And use it for example like this:

struct NonLinear {
    /* Some member function */
    double nonLinearFunc(double x, double y, int m) {
        return (x + y) * m; // (Not non-linear but serving as a simple example.)
    }
};

int main() {
    Solver s;
    NonLinear nl;

    // Use standard library call wrapper for member functions.
    auto c = std::mem_fn(&NonLinear::nonLinearFunc);

    // When using call wrapper you need to pass instance 'nl' as parameter.
    std::cout << s.funcEvaluation(c, nl, 1.0, 2.0, 2) << std::endl;

    // Outputs 6.0
}

Live example

1: You will need C++1y support for function return type deduction to work.

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 598319

It sounds like you want Solver::FuncEvaluation() to execute Nonlinear::NonlinearFunc(), is that correct? If so, I would do it like this:

class Evaluatable
{
public:
   virtual double Evaluate(ParameterList) = 0;
};


class Nonlinear : public Evaluatable
{
public:
   double Evaluate(ParameterList);
};

class Solver
{
public:
   double FuncEvaluation(Evaluatable &expression, ParameterList);
};

double Solver::FuncEvaluation(Evaluatable &expression, ParameterList params)
{
    return expression.Evaluate(params);
}

main()
{
    Nonlinear nl;
    Solver solve;
    double a;
    a = solve.FuncEvaluation(nl, ParameterList);
}

Upvotes: 2

lisu
lisu

Reputation: 2273

If you want just to evaluate the function, you don't actually need to use the pointer to member, you can just make an outright call:

class Solver
{
 public:
   Solver(Nonlinear& nl) : mNl(nl) {}
   double FuncEvaluation(ParameterList) //evaluate a function
 private:
   Nonlinear& mNl;
}; 

Solver::FuncEvaluation(ParameterList l)
{
  return mNl.NonLinearFunc(l);
}

Otherwise you'd have to use pointer to the member function AND still pass object instance.

Upvotes: 1

Related Questions