1

I have the following design problem and am seeking for the most elegant and even more important most efficient solution as this problem comes from a context where performance is an issue. Simply spoken I have a class "Function_processor" that does some calculations for real functions (e.g. calculates the roots of a real function) and I have another class "A" that has different such functions and needs to use the Function_processor to perform calculations on them.

The Function_processor should be as generic as possible (e.g. do not provide interfaces for all sorts of different objects), but merely stick to its own task (do calculations for any functions).

#include "function_processor.h"

class A {
    double a;
public:
    A(double a) : a(a) {}
    double function1(double x) {
        return a*x;
    }
    double function2(double x){
        return a*x*x;
    }

    double calculate_sth() {
        Function_processor function_processor(3*a+1, 7);
        return function_processor.do_sth(&function1);
    }
};

class Function_processor {
    double p1, p2;

public:
    Function_processor(double parameter1, double parameter2);

    double do_sth(double (*function)(double));
    double do_sth_else(double (*function)(double));
};

Clearly I can not pass the member functions A::function1/2 as in the following example (I know that, but this is roughly what I would consider readable code). Also I can not make function1/2 static because they use the non-static member a. I am sure I could use sth like std::bind or templates (even though I have hardly any experience with these things) but then I am mostly concerned about the performance I would get.

What is the best (nice code and fast performance) solution to my problem ?

Thanks for your help !

user1304680
  • 700
  • 2
  • 5
  • 18
  • [C++ Fast Delegate](http://stackoverflow.com/questions/4298408/5-years-later-is-there-something-better-than-the-fastest-possible-c-delegate), it is as fast as you can get. – yngccc Oct 14 '13 at 18:33
  • if this whole problem smells like bad code / design to you I am also happy to hear why and what might be a better way to achieve the same functionality – user1304680 Oct 14 '13 at 18:35
  • @yngum: which solution do you mean specifically ? – user1304680 Oct 14 '13 at 18:41
  • there are multiple solutions in there, you will have to pick the one that suit your need, the most voted answer is probably a good candidate. I would profile first, if it is not the bottleneck I would just use `std::function`. – yngccc Oct 14 '13 at 18:48
  • well, your link references to another SO question that has two answers and both the question and the most popular answer have links to even longer articles. I am happy you pushed me in the right direction, but I was hoping I would get a concrete answer so I do not have to read through extensive articles to get to a solution. – user1304680 Oct 14 '13 at 18:52
  • 2
    like I said, you asked for performance, and unfortunately to get that you have to go ugly in C++. Or u can use `std::function` and `std::bind` and be done with it. – yngccc Oct 14 '13 at 18:54
  • thats is good to know. I was not sure whether I am simply not aware of some standard solution or I am facing a problem that can not be answered so easily. – user1304680 Oct 14 '13 at 19:21

2 Answers2

1

This is not really the best way to do this, either from a pure OO point of view or a functional or procedural POV. First of all, your class A is really nothing more than a namespace that has to be instantiated. Personally, I'd just put its functions as free floating C-style ones - maybe in a namespace somewhere so that you get some kind of classification.

Here's how you'd do it in pure OO:

class Function
{
    virtual double Execute(double value);
};
class Function1 : public Function
{
    virtual double Execute(double value) { ... }
};

class FunctionProcessor
{
    void Process(Function & f)
    {
         ...
    }
}

This way, you could instantiate Function1 and FunctionProcessor and send the Function1 object to the Process method. You could derive anything from Function and pass it to Process.

A similar, but more generic way to do it is to use templates:

template <class T>
class FunctionProcessor
{
    void Process()
    {
        T & function;
        ...
    }
}

You can pass anything at all as T, but in this case, T becomes a compile-time dependency, so you have to pass it in code. No dynamic stuff allowed here!

Here's another templated mechanism, this time using simple functions instead of classes:

template <class T>
void Process(T & function)
{
    ...
    double v1 = function(x1);
    double v2 = function(x2);
    ...
}

You can call this thing like this:

double function1(double val)
{
    return blah;
}

struct function2
{
    double operator()(double val) { return blah; }
};

// somewhere else
FunctionProcessor(function1);
FunctionProcessor(function2());

You can use this approach with anything that can be called with the right signature; simple functions, static methods in classes, functors (like struct function2 above), std::mem_fun objects, new-fangled c++11 lambdas,... And if you use functors, you can pass them parameters in the constructor, just like any object.

That last is probably what I'd do; it's the fastest, if you know what you're calling at compile time, and the simplest while reading the client code. If it has to be extremely loosely coupled for some reason, I'd go with the first class-based approach. I personally think that circumstance is quite rare, especially as you describe the problem.

If you still want to use your class A, make all the functions static if they don't need member access. Otherwise, look at std::mem_fun. I still discourage this approach.

shash
  • 965
  • 8
  • 16
  • this is interesting. class A is really a namespace that has to be instantiated, but I have other classes that share some behaviour with class A so I was hoping I could derive them all from a base class. therefore I might choose your first example and make Function_processor work with the base type (not exactly what I wanted but probably ok). your last example I can not use unless I give up on the concept that A is a class. – user1304680 Oct 14 '13 at 19:33
  • You can use the third one with a class - just overload `operator()` like I did with the struct. In C++, the only difference between a class and a struct is that struct members are public by default. You can also look into `std::mem_fun` or one of the bind family of functions to create something to pass to FunctionProcessor. It can remain a class and you can bind to its member functions. – shash Oct 14 '13 at 23:10
  • the problem with operator() is that A has multiple functions with the same signature. I think I will use FastDelegate now. – user1304680 Oct 15 '13 at 07:18
0

If I understood correctly, what you're searching for seems to be pointer to member functions:

double do_sth(double (A::*function)(double));

For calling, you would however also need an object of class A. You could also pass that into function_processor in the constructor.

Not sure about the performance of this, though.

codeling
  • 11,056
  • 4
  • 42
  • 71
  • thank you, but sorry this is not what I am looking for. this way I would have to write a function_processor constructor specifically for A or overload do_sth the way you mentioned. next time I need the same for class B and I have to change function_processor again and I dont want that. – user1304680 Oct 14 '13 at 18:46