#include using yorel::multi_methods::virtual_; #include using namespace std; class Geometry { public: virtual ~Geometry() {} }; class Arc : public Geometry { public: virtual ~Arc() {} }; class Edge : public Geometry { public: virtual ~Edge() {} }; class Painter { public: void paint(Geometry& g); private: int counter = 0; template friend class paintObject_specialization; }; MULTI_METHOD(paintObject, void, virtual_&, Painter&); BEGIN_SPECIALIZATION(paintObject, void, Geometry& g, Painter& p) { cout << "painting geometry\n"; p.counter++; //accessible now } END_SPECIALIZATION; BEGIN_SPECIALIZATION(paintObject, void, Arc& a, Painter& p) { next(a, p); //passing the Painter cout << "painting arc\n"; } END_SPECIALIZATION; BEGIN_SPECIALIZATION(paintObject, void, Edge& e, Painter& p) { next(e, p); //passing the Painter cout << "painting edge\n"; } END_SPECIALIZATION; void Painter::paint(Geometry& g) { //passing the Painter paintObject(g, *this); } //I cannot change the Geometry classes in my case MM_FOREIGN_CLASS(Geometry); MM_FOREIGN_CLASS(Arc, Geometry); MM_FOREIGN_CLASS(Edge, Geometry); int main(int argc, char *argv[]) { yorel::multi_methods::initialize(); Arc a; Edge e; Painter p; p.paint(a); p.paint(e); }