Categories
C++ Development

C++ Visitor Pattern overload [duplicate]

I have spent the past hours trying to find an elegant solution but however i am unable to.

Description: I would like to have a default implementation for a visitor functor in class visitor_base_all and then each of the derived classes for example visitor_override would define the method just for what it needs. I understand that this does not work because the operator() is not passed to the derived classes (due to C++ not overload across scopes which is fair enough), so the question is how to do this exactly?
I was thinking of doing it with overloaded lambdas or having a switch in the virtual base_class method and then each derived class overloading only the virtual methods called in that switch.

Regarding the lambdas, I am not sure on how to do it.
I have read the following before: pablo_arias arne-mertz and stack_overflow_question but i am still a bit confused on what would be the proper correct way forward.

Thank you for your time

Short question: Proper c++17 way of making below compile/work.

(Post comments-edit) My problem is more generalized for a big number of classes and a lot more types, so if possible i would prefer to template/generalize it somehow. Below is the example with just 1 derived class, but what would be a proper way with having 10 classes? (I wouldn’t want to declare using in each of them if it can be avoided).

#include <variant>

struct A{};
struct B{};
struct C{};
using type_x = std::variant<A,B,C>;

class base_class
{
protected:
    struct visitor_base_all
    {
        void operator()(const A& a){std::cout<<"A_base" << std::endl;}
        void operator()(const B& b){std::cout<<"B_base" << std::endl;}
        void operator()(const C& c){std::cout<<"C_base" << std::endl;}
    };
    virtual void run(type_x evt){return std::visit(visitor_base_all{}, evt);}
};

class derived_class :public base_class
{
    struct visitor_override : public visitor_base_all
    {
        void operator()(const C& c){};
    };
     virtual void run(type_x evt){return std::visit(visitor_override{}, evt);}
};

Leave a Reply

Your email address will not be published. Required fields are marked *