quetzalfir
quetzalfir

Reputation: 568

Store a function c++, and call it later

I'm developing an app, in which I have a lot of small algorithms, each algorithm represented by some lines of code, so I want to store that few lines of code as functions, but not only that, I have to store some data that each algorithm has, so I decided to make a "Algorithm" class, in which, I would have in a "variable" the function stored. So, I can use it later.

I don't know if this is possible or if there is another way to reach that. I think there would be problems with local variables or private members of the class where my "algorithms" are.

class Patterns {

private:
    double line;
    double addPoint(char n) {line += n;}

public:
    double addPattern(int m) {
        double tmp = 0;
        char param;
        // some calculations with m

        // many calls to addPoint, "algorithm"
        tmp += addPoint(param); // param1
        tmp += addPoint(param); // param2
        tmp += addPoint(param); // param3
        tmp += addPoint(param); // param4

        return tmp;
    }
}

just a little sample, I want to store all those lines of "addPoints()" in only one function, and use whenever I want, something like this

class Patterns {

private:
    double line;
    double addPoint(char n) {line += n;}

public:
    double addPattern(int m) {
        double tmp = 0;
        // some calculations with m

        /**
         * vector of Algorithm class, get any Algorithm, and of that,
         * return the stored function, so I can use it as in the above sample
         */
        auto fn = vec->back()->getFunction();
        tmp += fn(m)

        return tmp;
    }
}

Edit: this question includes the use of the library <functional>

Upvotes: 1

Views: 640

Answers (2)

sameerkn
sameerkn

Reputation: 2259

There are multiple ways to encounter the problem using OOD. Since you have many algorithms along with their respective data then it makes sense to create classes for such algorithm. Now, as far as OOD is concerned then , you can use Design Pattern : Strategy.

It goes like this:

Define an interface for all you algorithm

class IAlgorithm
{
    public:
    virtual int Execute(/*external parameter list on which all algorithm depend.*/) = 0;        
};

Now, define different algorithms inheriting from interface IAlgorithm.

class CAlgorithm_Type1 : public IAlgorithm
{
    private:
        /* all the data members internally and exclusively used by this algorithm*/
    public:
        int Execute(/*external parameter list on which all algorithm depend.*/);
};

class CAlgorithm_Type2 : public IAlgorithm
{
    private:
        /* all the data members internally and exclusively used by this algorithm*/
    public:
        int Execute(/*external parameter list on which all algorithm depend.*/);
};

Now define the client of these algorithms.

class Patterns 
{
    private:
        double line;
        double addPoint(char n) {line += n;}
        IAlgorithm *m_pAlgorithm;

    public:
        SetAlgorithm(IAlgorithm *_pAlgorithm)
        {
            m_pAlgorithm = _pAlgorithm;
        }
        double addPattern(int m) {
        double tmp = 0;           

        tmp += m_pAlgorithm->Execute(m);

        return tmp;
    }
};

Now as per requirement there can be an Algorithm Factory

class ALGORITHM_LIBRARY
{
    public:
        enum TYPE
        {
            ALGORITHM_TYPE1,
            ALGORITHM_TYPE2,
            TOTAL_ALGORITHMS
        };

    ALGORITHM_LIBRARY()
    {
        m_Algorithms[ALGORITHM_LIBRARY::ALGORITHM_TYPE1] = new CAlgorithm_Type1();
        m_Algorithms[ALGORITHM_LIBRARY::ALGORITHM_TYPE2] = new CAlgorithm_Type2();
    }
    ~ALGORITHM_LIBRARY()
    {
        map<ALGORITHM_LIBRARY::TYPE, IAlgorithm*>::iterator it;
        for(it = m_Algorithms.begin(); it != m_Algorithms.end(); ++it)
        {
            delete it->second;
        }
    }
    IAlgorithm* GetAlgorithm(ALGORITHM_LIBRARY::TYPE _enumAlgorithmType)
    {
        return m_Algorithms[_enumAlgorithmType];
    }

    private:
        map<ALGORITHM_LIBRARY::TYPE, IAlgorithm*> m_Algorithms;
};


ALGORITHM_LIBRARY g_oAlgorithmLibrary;

enum enumAlgorithmType = ALGORITHM_LIBRARY::ALGORITHM_TYPE2;
Pattern Obj;
Obj.SetAlgorithm(g_oAlgorithmLibrary.GetAlgorithm(enumAlgorithmType));
Obj.addPattern(20);

Upvotes: 2

Ajay
Ajay

Reputation: 18441

How does this sound:

#include <vector>
#include <functional>

int test(int a)
{
    return a*2;
}
int main()
{
    using namespace  std;
    vector < function<int(int)>> fv;

    fv.push_back([](int a) {return a + 5; });

    (fv.back())(10);

    fv.push_back(test);

    (fv.back())(240);
}

For your class, you'd need to change the type of function's template argument.

EDIT (minimal class example):

class Pattern
{
    double addPoint(char n)
    {
        return n * 99.0;
    }
    double addPoint2(char n)
    {
        return n * 188.25;    
    }

    vector < function<double(char)>> funcs;
public:
    Pattern()
    {
        funcs.push_back(std::bind(&Pattern::addPoint, this, placeholders::_1));         
        funcs.push_back(std::bind(&Pattern::addPoint2, this, placeholders::_1));
    }

    void Call()
    {
        cout << (funcs.back())('A');
    }
};
int main()
{
    Pattern p;
    p.Call();
}

However, if the functions are global or static, you don't need to do bind thing.

Upvotes: 3

Related Questions