Hi all,

I've scoured the internet for examples that would allow me to figure out how to apply functors in my specific case, but I just can't seem to make the shift from the examples I find to figuring out how to use it for my own code.

Here is a reduced example of what I am currently facing. I have three files, that I am listing one by one here. The first file is Solver.h:

#ifndef SOLVER_H
#define SOLVER_H

// Include statements.
#include "MathematicalMethods.h"

// Forward declaration.
class MathematicalMethods;

class Solver
{
public:
    Solver(){};

    ~Solver(){};

    void setMathematicalMethod( MathematicalMethods* mathematicalMethod )
    {
        mathematicalMethod_ = mathematicalMethod;
    };

    void solve()
    {
        mathematicalMethod_->setDoubleTakingFunction( &Solver::computeValue, this );
        mathematicalMethod_->execute();
    };

    double computeValue( double& value )
    {
        return 2.0 * value;
    };

protected:
private:
    MathematicalMethods* mathematicalMethod_;
};

#endif // SOLVER_H

The second file is MathematicalMethods.h:

#ifndef MATHEMATICALMETHODS_H
#define MATHEMATICALMETHODS_H

// Include statements.
#include <iostream>
#include "Solver.h"

// Forward declarations.
class Solver;

class MathematicalMethods
{
public:
    typedef double ( Solver::*pointerToDoubleTakingFunction ) ( double& );

    MathematicalMethods(){};

    ~MathematicalMethods(){};

    void setDoubleTakingFunction( pointerToDoubleTakingFunction doubleTakingFunction,
                                                   Solver* pointerToSolver )
    {
        pointerToDoubleTakingFunction_ = doubleTakingFunction;
        pointerToSolver_ = pointerToSolver;
    };

    void setValue( const double& value )
    {
        value_ = value;
    };

    void execute()
    {
        std::cout << ( pointerToSolver_->*pointerToDoubleTakingFunction_ )( value_ ) << std::endl;
    };

protected:
    pointerToDoubleTakingFunction pointerToDoubleTakingFunction_;

    Solver* pointerToSolver_;

    double value_;
private:
};

#endif // MATHEMATICALMETHODS_H

The last file contains the main function:

// Include statements.
#include "Solver.h"
#include "MathematicalMethods.h"

int main()
{
    MathematicalMethods* pointerToMathematicalMethod = new MathematicalMethods;

    pointerToMathematicalMethod->setValue( 10.0 );

    Solver mySolver;

    mySolver.setMathematicalMethod( pointerToMathematicalMethod );

    mySolver.solve();

    return 0;
}

This works fine for me and produces the intended output of 20.0 but there are a number of problems. Firstly, the code is not easily extensible to add other solvers that make use of the MathematicalMethods class. Secondly, in the actual implementation that I have, both Solver and MathematicalMethods belong to inheritance trees, which means that the circular class declarations become quite complicated, and for some reason my compiler at time just refuses to compile the code. In other words, the code doesn't seem to be stable at all and I can't seem to figure out how to stabilize it.

My understanding about functors is that they make this whole task a whole lot easier. Additionally, if I understand the examples that I've read correctly, the use of functors would also make it a trivial task to add additional solvers that make use of the MathematicalMethods class.

I'm generally quite good at reading tutorials and transcribing them to my application, but for some reason I'm having a brain freeze and I can't see how I should go about rewriting this code to make use of functors instead of the pointer-to-member function solution that I've got now.

I hope you someone here can give me a headstart so that I can get this sorted out asap.

My apologies if I've posed the question in a contorted manner or if the solution ends up being a straightfoward application of basic functor examples, I just don't see at the moment how to go about it.

Thanks in advance for your help!

Cheers,

Kartik

Recommended Answers

All 8 Replies

Just looking at your main, specifically this part :

mySolver.setMathematicalMethod( pointerToMathematicalMethod );
mySolver.solve();

intuitively, I would expect mySolver.solve() just delegate the job to the mathMaticalMethod. So what I am trying to say is that your computeValue(...) function
in your mySolver doesn't make sense to me. It should be contained in the mathematicalMethod.execute() function. So maybe you can set up some hierarchy like so :

#include <iostream>
#include <cmath>

using namespace std;

//Abstract Interface
struct IMathCommand{
	virtual double operator()(const double& value)const = 0;
	virtual ~IMathCommand(){};
};

class ZeroMathCommand : public IMathCommand{
	double operator()(const double& value)const{ return 0.0; }
};
class SquareMathCommand : public IMathCommand{
	double operator()(const double& value)const{ return value * value; }
};
class SinusMathCommand : public IMathCommand{
	double operator()(const double& value)const{ return std::sin(value); }
};
//Add more MathCommand if needed

class MathSolver{
private:
	IMathCommand *mathFunc_;
public:
	MathSolver() : mathFunc_(0){}
	
	void setMathCommand(IMathCommand* cmd){ 
		mathFunc_ = cmd; 
	}
	const IMathCommand& getMathCommand(){
		return *mathFunc_;
	}
	double execute(const double val = 0.0)const{ 		
		if(!mathFunc_) throw std::exception("Math function not set");
		return (*mathFunc_)(val);
	}	
};


int main(){

	MathSolver solver;

	SquareMathCommand sqrCmd;
	ZeroMathCommand zeroCmd;
	SinusMathCommand sinCmd;
	
	solver.setMathCommand(&sqrCmd);
	cout << solver.execute(10) << endl; //output 100

	solver.setMathCommand(&zeroCmd);
	cout << solver.execute(10) << endl; //ouput 0

	solver.setMathCommand( &sinCmd );
	cout << solver.execute(3.14/2.0) << endl; //output 1

	return 0;
}

It could definitely be better, for example not using raw pointers or it might not fit exactly to your needs, but its a start.

I think your application would be better (or more easily) solved with the use of dynamic polymorphism. Consider something like this:

//SOLVER_BASE_H

#ifndef SOLVER_BASE_H
#define SOLVER_BASE_H

// Forward declaration.
class MathematicalMethods;

class SolverBase {
  protected:
    virtual double computeValue( double& value ) = 0; //pure virtual function in the base class.
  public:
    friend class MathematicalMethods;
};

#endif


//SOLVER_H
#ifndef SOLVER_H
#define SOLVER_H

// Include statements.
#include "MathematicalMethods.h"

class Solver : public SolverBase {
  public:
    Solver(){};

    ~Solver(){};

    void setMathematicalMethod( MathematicalMethods* mathematicalMethod ) {
      mathematicalMethod_ = mathematicalMethod;
    };

    void solve() {
      mathematicalMethod_->setSolver( this );
      mathematicalMethod_->execute();
    };

  protected:
    double computeValue( double& value )
    {
        return 2.0 * value;
    };

  private:
    MathematicalMethods* mathematicalMethod_;
};
#endif


//MATHEMATICALMETHODS_H

#ifndef MATHEMATICALMETHODS_H
#define MATHEMATICALMETHODS_H

// Include statements.
#include <iostream>
#include "SolverBase.h"

class MathematicalMethods {
  public:
    MathematicalMethods(){};
    ~MathematicalMethods(){};

    void setDoubleTakingFunction( SolverBase* pointerToSolver )
    {
      pointerToSolver_ = pointerToSolver;
    };

    void setValue( const double& value )
    {
        value_ = value;
    };

    void execute()
    {
        std::cout << pointerToSolver_->computeValue( value_ ) << std::endl;
    };

  protected:
    SolverBase* pointerToSolver_;

    double value_;
  private:
};

#endif // MATHEMATICALMETHODS_H

If you absolutely want to use functors or other concepts similar to that, I would recommend doing something similar to the following implementation (which is something I have posted a few times already on older threads on this forum... it is quite trivial to adapt this to your application, by just making the function take and return a double):

#include <iostream>

//define a default policy class for all the responder policies 
struct NoRespondPolicy {
  void operator()() {
    std::cout << "not responding..." << std::endl;
  };
};

//make the Button class templated with the responding policy:
template<class OnRelease = NoRespondPolicy>
class Button {
  private:
    OnRelease responder;
  public:
    Button() { };
    Button(OnRelease aResponder) : responder(aResponder) { };
    void setActionOnReleased(OnRelease aResponder ) { 
      responder = aResponder;
    };
    void mouseReleased() {
      std::cout << "mouse released" << std::endl;
      responder();
    };
};

//create a special policy for pointer to member functions:
template<class T>
class MemberFuncRespond {
  public:
    typedef void (T::*VoidFuncPtr)();
  private:
    T* Obj;
    VoidFuncPtr Func;
  public:
    MemberFuncRespond(T* aObj, VoidFuncPtr aFunc) : Obj(aObj), Func(aFunc) { };
    void operator() () {
      if(Obj)
        (Obj->*Func)();
    };
};

//Make whatever class you want to use as respond:
class AClass {
  public:
    //....
    void OnRelease() {
      std::cout << "responding with on release function..." << std::endl;
    };
    typedef void (AClass::*VoidFunc)();
    typedef MemberFuncRespond<AClass> Responder;
    Responder getResponder(VoidFunc FPtr) { return Responder(this,FPtr); };

    void operator()() {
      std::cout << "responding with operator ()..." << std::endl;
    };
};

void GlobalOnRelease() {
  std::cout << "responding with global function..." << std::endl;
};

//then you set it up as:
int main() {
  AClass myResponder;

  Button<> myButton1; //no response (default policy)  
  myButton1.mouseReleased();

  Button<AClass&> myButton2(myResponder); //respond with AClass.operator()
  myButton2.mouseReleased();

  Button< AClass::Responder > myButton3(myResponder.getResponder(&AClass::OnRelease)); //respond with AClass.OnRelease()
  myButton3.mouseReleased();

  Button<void (*)()> myButton4(&GlobalOnRelease); //respond with GlobalOnRelease()
  myButton4.mouseReleased();

  return 0;
};

Thanks for all the input, I guess I kinda understand the solutions presented, but I think I might have confused the matter by presenting the original classes in a contorted manner.

If there is an alternative solution to using functors, I am definitely open to it. There is no requirement to have to use functors, the only requirement is to make the code work.

I am restating the code now with better names to make it clearer what it is that I am trying to achieve:

newtonRaphson.h:

#ifndef NEWTONRAPHSON_H
#define NEWTONRAPHSON_H

// Include statements.
#include <iostream>
#include <cmath>
#include "orbitTargeter.h"

// Forward declarations.
class OrbitTargeter;

class NewtonRaphson
{
public:
    typedef double ( OrbitTargeter::*pointerToDoubleTakingFunction ) ( double& );

    NewtonRaphson(){};

    ~NewtonRaphson(){};

    void setInitialGuess( const double& initialGuess )
    {
        initialGuess_ = initialGuess;
        currentValue_ = initialGuess;
    }

    void setMathematicalFunction( pointerToDoubleTakingFunction doubleTakingFunction,
                                  OrbitTargeter* pointerToSolver )
    {
        pointerToComputeFunction_ = doubleTakingFunction;
        pointerToSolver_ = pointerToSolver;
    };

    void setFirstDerivativeMathematicalFunction( pointerToDoubleTakingFunction doubleTakingFunction,
                                                 OrbitTargeter* pointerToSolver )
    {
        pointerToFirstDerivativeComputeFunction_ = doubleTakingFunction;
        pointerToSolver_ = pointerToSolver;
    };

    void execute()
    {
        // First step of algorithm.
        nextValue_ = initialGuess_;

        // Loop until converage or maximum number of iterations reached.
        for ( unsigned int i = 0; i < 20; i++ )
        {
            // Update current value.
            currentValue_ = nextValue_;

            // Update next value.
            nextValue_ = currentValue_
                         - ( pointerToSolver_->*pointerToComputeFunction_ )( currentValue_ )
                         / ( pointerToSolver_->*pointerToFirstDerivativeComputeFunction_ )( currentValue_ );

            // Check if root value has converged.
            if ( fabs( currentValue_ - nextValue_ ) < 1e-12 )
            {
                std::cout << "Value of root is: " << nextValue_ << std::endl;
                std::cout << "Number of iterations required was: " << i << std::endl;
                break;
            }

            if ( i == 19 )
            {
                std::cout << "Maximum number of iterations reached."  << std::endl;
            }
        }
    };

protected:
    pointerToDoubleTakingFunction pointerToComputeFunction_;

    pointerToDoubleTakingFunction pointerToFirstDerivativeComputeFunction_;

    OrbitTargeter* pointerToSolver_;

    double initialGuess_;

    double currentValue_;

    double nextValue_;
private:
};

#endif // NEWTONRAPHSON_H

OrbitTargeter.h

#ifndef ORBITTARGETER_H
#define ORBITTARGETER_H

// Include statements.
#include "newtonRaphson.h"

// Forward declaration.
class NewtonRaphson;

class OrbitTargeter
{
public:
    OrbitTargeter(){};

    ~OrbitTargeter(){};

    void setNewtonRaphson( NewtonRaphson* newtonRaphson )
    {
        newtonRaphson_ = newtonRaphson;
    };

    void solve()
    {
        newtonRaphson_->setMathematicalFunction( &OrbitTargeter::computeValue, this );
        newtonRaphson_->setFirstDerivativeMathematicalFunction( &OrbitTargeter::computeFirstDerivativeValue, this );
        newtonRaphson_->execute();
    };

    double computeValue( double& value )
    {
        return value * value - 3.0;
    };

    double computeFirstDerivativeValue( double& value )
    {
        return 2.0 * value;
    };

protected:
private:
    NewtonRaphson* newtonRaphson_;
};

#endif // ORBITTARGETER_H

main.cpp

// Include statements.
#include "orbitTargeter.h"
#include "newtonRaphson.h"

int main()
{

    NewtonRaphson* pointerToNewtonRaphson = new NewtonRaphson;

    pointerToNewtonRaphson->setInitialGuess( 5.0 );

    OrbitTargeter myOrbitTargeter;

    myOrbitTargeter.setNewtonRaphson( pointerToNewtonRaphson );

    myOrbitTargeter.solve();

    return 0;
}

These are all dummy classes, as my code is much longer, but it captures the essence of the code.

The NewtonRaphson class implements the Newton-Raphson root-finding algorithm (http://en.wikipedia.org/wiki/Newton's_method).

The way I need to solve this is by making sure that NewtonRaphson is able to accept functions from any other class that requires it, such as OrbitTargeter. The problem I have at present with this solution (other than the problems I have faced regarding the circular dependencies) is that if there was another class that would require NewtonRaphson e.g., AnotherOrbitTargeter, then I would have to add a specific typedef for a pointer to member functions of that class.

My understanding is that in C++ there are much more elegant ways of handling this.

I'm sorry if I am repeating myself, but I'm not quite sure in this context how to apply the solutions you've presented, particularly because I think I confused the matter between what each class was doing.

Essentially, to summarize, NewtonRaphson should be as stand-alone as possible, with OrbitTargeter depending on NewtonRaphson. Hence, the code additions/changes should be in OrbitTargeter as much as possible and not in NewtonRaphson.

Thanks a lot in advance!

Cheers,

Kartik

I don't think I can give examples that are any clearer than those I already have posted. I understand your application and I have implemented similar problems many times before (optimization methods and AI methods often involve the same basic setup of a function evaluator and a solver or optimizer). I use either one of the two methods that I previously posted (which one I choose depends on minor details only). Take a second look at them... really all you need to do to adapt it to your problem is to change the names, I'm not gonna do that for you.

I don't think I can give examples that are any clearer than those I already have posted. I understand your application and I have implemented similar problems many times before (optimization methods and AI methods often involve the same basic setup of a function evaluator and a solver or optimizer). I use either one of the two methods that I previously posted (which one I choose depends on minor details only). Take a second look at them... really all you need to do to adapt it to your problem is to change the names, I'm not gonna do that for you.

Thanks for your response and I understand that it should be a trivial task is altering the code you presented for my needs. I think though that I've managed to narrow down the specific issue that I'm having.

In the dynamic polymorphism example you gave, in the SolverBase base class, you made the computeValue function pure virtual. I understand how this solution works, but I guess it wasn't clear in what I presented earlier that the problem also stems from the fact that the MathematicalMethods class needs to be able to work with functions with any names in a range of Solver classes.

In other words, this line from the MathematicalMethods class is at the crux of my problem:

std::cout << pointerToSolver_->computeValue( value_ ) << std::endl;

The problem namely is that it's not computeValue( value_ ) that needs to be called but a function pointer that is passed to the class so that any function of the structure: double funcName( double& value ) would work.

I guess I'm pretty close to the solution, however this last bit is what is causing me a headache.

I think that I might be able to solve the problem by templatizing SolverBase so that it can work with pointers to any Objects that contain function pointers to any member functions of the structure re: double funcName( double& value ) , but I am not sure how.

Your input with regards to solving this problem i.e., making the code accept any function and not just ones name computeValue(), would be much appreciated.

Thanks a lot in advance,

Cheers,

Kartik

Ok, then consider this addition:

//SOLVER_BASE_H

#ifndef SOLVER_BASE_H
#define SOLVER_BASE_H

// Forward declaration.
class MathematicalMethods;

class SolverBase {
  protected:
    virtual double computeValue( double& value ) = 0; //pure virtual function in the base class.
  public:
    friend class MathematicalMethods;
};

template <class T>
class SolverFunctor : public SolverBase {
  public:
    typedef double (T::*EvaluationFuncPtr)(double&);
  protected:
    T* ObjPtr;
    EvaluationFuncPtr FuncPtr;

    virtual double computeValue(double& value) { 
      if((ObjPtr) && (FuncPtr))
        return (ObjPtr->*FuncPtr)(value);
      else
        return 0.0;
    };
  public
    SolverFunctor(T* aObjPtr, EvaluationFuncPtr aFuncPtr) : ObjPtr(aObjPtr), FuncPtr(aFuncPtr) { };
    virtual ~SolverFuncPtr() { };
};

#endif


//SOLVER_H
#ifndef SOLVER_H
#define SOLVER_H

// Include statements.
#include "MathematicalMethods.h"

class Solver {
  private:
    SolverFunctor<Solver> mFunctor;
  public:
    double execute( double& value ) //notice, any name
    {
        return 2.0 * value;
    }; 

    Solver() : mFunctor(this,&Solver::execute) {}; //create the functor in the constructor.

    ~Solver(){};

    void setMathematicalMethod( MathematicalMethods* mathematicalMethod ) {
      mathematicalMethod_ = mathematicalMethod;
    };

    void solve() {
      mathematicalMethod_->setSolver( mFunctor ); //pass the functor to the mathmethods.
      mathematicalMethod_->execute();
    };

  private:
    MathematicalMethods* mathematicalMethod_;
};
#endif


//MATHEMATICALMETHODS_H

#ifndef MATHEMATICALMETHODS_H
#define MATHEMATICALMETHODS_H

// Include statements.
#include <iostream>
#include "SolverBase.h"

class MathematicalMethods {
  public:
    MathematicalMethods(){};
    ~MathematicalMethods(){};

    void setDoubleTakingFunction( SolverBase* pointerToSolver )
    {
      pointerToSolver_ = pointerToSolver;
    };

    void setValue( const double& value )
    {
        value_ = value;
    };

    void execute()
    {
        std::cout << pointerToSolver_->computeValue( value_ ) << std::endl;
    };

  protected:
    SolverBase* pointerToSolver_;

    double value_;
  private:
};

#endif // MATHEMATICALMETHODS_H

This solution is basically somewhere in-between my first and second original suggestions. The class SolverFunctor is an adaptor, it allows you to adapt a class you have already (Solver) with some restrictions (like the names of the functions or the inheritance cannot be changed) such that it fits in another "framework" (i.e. the mathmethods-to-SolverBase polymorphic connection). There is an overhead to this method (storing the SolverFunctor in the class Solver, so this is why I usually use either the first or second original solutions, because both of them have minimum run-time overhead. In your situation, it is totally fine to use an adaptor like this, but still, the generic programming technique (second original solution) is still a bit better if it can be done.

My understanding is that in C++ there are much more elegant ways of handling this.

There are. For instance, using a polymorphic call wrapper.
std::function (C++1x), std::tr1::function (C++98 with tr1 extensions) or boost::function (vanilla C++98).

For example C++98 with boost:

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

struct NewtonRaphson
{
    typedef boost::function< double( double& ) > function_t ;

    void set_it( function_t fun ) { function = fun ; }

    double call_it( double& arg ) { return function(arg) ; }

    function_t function ;
};

float free_fun( double& d )
{ std::cout << "::freefun( " << d << " ) => " ; return d += 1.0 ; }

struct function_object
{
  long double operator() ( double& d ) const
  { std::cout << "::function object( " << d << " ) => " ; return d += 2.0 ; }
};

struct asolver
{
    double compute( double& d ) const
    { std::cout << "asolver::compute( " << d << " ) => " ; return d += 3.0 ; }
};

int main()
{
    NewtonRaphson nr ;
    double d = 10.5 ;

    nr.set_it( free_fun ) ;
    std::cout << nr.call_it(d) << '\n' ;

    nr.set_it( function_object() ) ;
    std::cout << nr.call_it(d) << '\n' ;

    asolver solver ;
    nr.set_it( boost::bind( &asolver::compute, solver, _1 ) ) ;
    std::cout << nr.call_it(d) << '\n' ;
}

It is not shown in the snippet, but you could also wrap a lambda function.

commented: very nice! Didn't know about that! +1

Thanks for all the feedback everyone. I managed to sort it out using the idea of using an adaptor with polymorphism. Learned a whole lot more in the process about things in C++ so I'm happy :)

Solved!

Kartik

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.