Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ how to create a std::vector of functors

Tags:

c++

class A
{
public:
    int x;
    //create a vector of functors in B and C here
};

class B
{
public:
    struct bFunctor
    {
        void operator()() const
        {
            //some code
        }
    };
};

class C
{
public:
    struct cFunctor
    {
        void operator()() const
        {
            //some code
        }
    };

};

void main()
{
 A obj;
 //iterate through the vector in A and call the functors in B and C
}

My question is what should be the format of the vector in class A for calling functors in B and C? Or is the only way this is possible to have a base functor in A and make the functors in B and C derive from it? Or is there a better approach?

like image 264
sn710 Avatar asked Mar 23 '23 00:03

sn710


1 Answers

There are essentially two ways to approach this (that I can think of ATM):

Note: I would rename cFunctor and bFunctor to simply Functor in both cases. They are nested inside respective classes and thus such prefix makes little sense.

Type erased

Example of type erasure is std::function.

class A {
public:
    int x;
    std::vector<std::function<void(void)>> functors;
    
    A() : functors { B::bFunctor(), C::cFunctor() }
    { }
};

If you need the functors to have more advanced behaviour, Boost.TypeErasure any might help.

Polymorphic

  1. Create an abstract functor type.
  2. Make B::bFunctor and C::cFunctor inherit from it.
  3. Store vector of that abstract functor type smart pointers.

struct AbstractFunctor {
    virtual void operator()() const = 0;
};

class B {
public:
    struct Functor : public AbstractFunctor {
       void operator()() const {
       //some code
       }
    };
};

class A {
public:
    int x;
    std::vector<std::unique_ptr<AbstractFunctor>> functors;
    
    A() { 
        // this could most probably be shortened with make_unique
        functors.emplace_back(std::unique_ptr<AbstractFunctor>(new B::Functor()));
        functors.emplace_back(std::unique_ptr<AbstractFunctor>(new C::Functor()));
    }
};
like image 51
Bartek Banachewicz Avatar answered Mar 25 '23 14:03

Bartek Banachewicz