vendredi 8 janvier 2021

How to instruct a polymorphic functor in a container to do its job and return results?

I have a std::vector<> of pointers to a base functor. This container, a calculator class, should be able to hold onto an arbitrary number of these function objects that calculate arbitrary statistics.

The part I'm struggling with is how to write a method for the container class, that iterates over these pointers, picks the one you're interested in out of hte group, tells it to do its job by calling operator(), then returns the result.

Here's some code that illustrates the idea:

#include <iostream>
#include <memory> //shared_ptr
#include <vector>

class BaseFunctor{
    virtual double operator()(std::vector<double> inputs) = 0;  
};

class Sum : public BaseFunctor{
    double operator() (std::vector<double> inputs){ 
        double sum (0.0);
        for(auto elem : inputs)
            sum += elem;
        return sum;
    }
};

class Prod : public BaseFunctor{
    double operator() (std::vector<double> inputs){ 
        double sum (1.0);
        for(auto elem : inputs)
            sum *= elem;
        return sum;
    }
};

class Calculator {
private:
    std::vector<std::shared_ptr<BaseFunctor>> m_stats;
    std::vector<double> m_simple_data;
public:
    Calculator() 
        : m_simple_data({1.0, 2.0, 3.0}) {};
    void addStat(std::shared_ptr<BaseFunctor> stat) { 
        m_stats.push_back(stat); 
    }
    // calculate stat?
};

int main() {

    Calculator calc;
    calc.addStat(std::make_shared<Sum>());
    calc.addStat(std::make_shared<Prod>());
    
    return 0;
}

Now, how could I tell calc to give me the product, and only the product? Especially when I can't control what statistics the user ends up being interested in?

I imagine I could store the pointers in a map, instead, but that seems redundant: making the key have the same name as the class.

Aucun commentaire:

Enregistrer un commentaire