Pergunta

I'm trying to build a generic algorithm. So far I have achieved this using class hierarchy and pointers, as in the example below:

struct Base{
    virtual double fn(double x){return 0;}
};

class Derived : public  Base{
    double A;
public:
    Derived(double a) : A(a) {}
    double fn(double x) { return A*x;}
};

//Some other implementations

class algo{
    double T;
    std::unique_ptr<Base> b_ptr;
public:
    algo(double t, std::unique_ptr<Base>& _ptr); //move constructor...
    //Some constructors
    double method(double x){ return T*b_ptr->fn(x);}

};

This set up is then implemented as follows:

int main(){
    std::unique_ptr<Derived> ptr(new Derived(5.4));
    algo(3.2,ptr);
    method(2.4);

    return 0;
}

This is a very simple example, of course, but it serves for my question. From what I understand, using derived classes in this way means that the method is chosen at run-time rather than at compile time. Since I do not need any dynamic behaviour from my algorithm - everything is determined at compile time - this is a needless loss of efficiency. Is there a way to do the above at compile time, i.e. static polymorphism?

From what I understand, it's only possible to get static polymorphism using templates. I haven't been able to find a implement templates with non-primitive types, however. As in the example above, I need derived classes with non-default constructors, which doesn't seem to be possible... Could anyone offer any solutions as to how this might be done?

Foi útil?

Solução

Your Base class and Derived seem to represent a function only having a single member function, so we could most likely do away with the polymorphism completely and pass a function into algo:

#include <iostream>
#include <utility>

template <class Function>
class algo
{
    double t;
    Function fn;

public:
    algo(double t, const Function& fn)
        : t{t}, fn{fn}
    { }
    double method(double x){ return t * fn(x);}

};

template <class Function>
algo<Function> make_algo(double t, Function&& fn)
{
    return algo<Function>(t, std::forward<Function>(fn));
}

int main()
{
    const double someValue = 123;
    const double anotherValue = 987;

    auto algo = make_algo(anotherValue, [someValue](double otherValue) {
        return someValue * otherValue;
    });

    std::cout << std::fixed << algo.method(321) << std::endl;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top