The question is more likely theoretical.
Foreword Visitor Template:
class Visitor { public: virtual void VisitElementA(const ElementA& obj) = 0; virtual void VisitElementB(const ElementB& obj) = 0; }; class Element { public: virtual void Accept(Visitor& visitor) = 0; }; class ElementA : public Element { public: void Accept(Visitor& visitor) override { visitor.VisitElementA(*this); } }; class ElementB : public Element { public: void Accept(Visitor& visitor) override { visitor.VisitElementB(*this); } };
This VisitElementA element (const ElementA & obj) looks a little ugly, so using overload we can rewrite it like this:
class Visitor { public: virtual void Visit(const ElementA& obj) = 0; virtual void Visit(const ElementB& obj) = 0; };
And now we have two identical implementations of the Accept method in ElementA and ElementB:
void Accept(Visitor& visitor) override { visitor.Visit(*this); }
And such code should be added to ElementC, ElementD, etc. (if there)
Question : How to avoid this duplication?
The naive decision to place the Accept implementation inside the Element class (or some other intermediate class) will not work, because this pointer will point to the object as an object of the Element class, not ElementA or ElementB, and thus, in the best case, we get an error compilation or even incorrect behavior (if there is some overloaded Visit method for Element).
As I understand it, the problem is trying to combine compilation and runtime functions. But can there be some kind of template-based solution or a new C ++ 11 function or something else?
One note: I would appreciate it if you did not offer a solution with "macro magic" :).
source share