#include <iostream>
using namespace std;
class Derived1;
class Derived2;
class Visitor;
class Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1) = 0;
virtual void Accept(Visitor &iVisitor, Derived1& param2) = 0;
virtual void Accept(Visitor &iVisitor, Derived2& param2) = 0;
};
class Visitor
{
public:
virtual void Visit(Derived1 & param1, Derived1 ¶m2) { cout << "11\n"; }
virtual void Visit(Derived1 & param1, Derived2 ¶m2) { cout << "12\n"; }
virtual void Visit(Derived2 & param1, Derived1 ¶m2) { cout << "21\n"; }
virtual void Visit(Derived2 & param1, Derived2 ¶m2) { cout << "22\n"; }
};
class Derived1: public Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1)
{ param1.Accept(iVisitor, *this); }
virtual void Accept(Visitor &iVisitor, Derived1& param2)
{ iVisitor.Visit(*this, param2); }
virtual void Accept(Visitor &iVisitor, Derived2& param2)
{ iVisitor.Visit(*this, param2); }
};
class Derived2: public Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1)
{ param1.Accept(iVisitor, *this); }
virtual void Accept(Visitor &iVisitor, Derived1& param2)
{ iVisitor.Visit(*this, param2); }
virtual void Accept(Visitor &iVisitor, Derived2& param2)
{ iVisitor.Visit(*this, param2); }
};
void Visit(Visitor& visitor, Base& param1, Base& param2)
{
param2.Accept(visitor, param1);
}
int main() {
Derived1 d1;
Derived2 d2;
Visitor v;
Visit(v, d1, d1);
Visit(v, d1, d2);
Visit(v, d2, d1);
Visit(v, d2, d2);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgRGVyaXZlZDE7CmNsYXNzIERlcml2ZWQyOwpjbGFzcyBWaXNpdG9yOwpjbGFzcyBCYXNlCnsKcHVibGljOgogICB2aXJ0dWFsIHZvaWQgQWNjZXB0KFZpc2l0b3IgJmlWaXNpdG9yLCBCYXNlJiBwYXJhbTEpID0gMDsKICAgdmlydHVhbCB2b2lkIEFjY2VwdChWaXNpdG9yICZpVmlzaXRvciwgRGVyaXZlZDEmIHBhcmFtMikgPSAwOwogICB2aXJ0dWFsIHZvaWQgQWNjZXB0KFZpc2l0b3IgJmlWaXNpdG9yLCBEZXJpdmVkMiYgcGFyYW0yKSA9IDA7Cn07CgpjbGFzcyBWaXNpdG9yCnsKcHVibGljOgogICAgdmlydHVhbCB2b2lkIFZpc2l0KERlcml2ZWQxICYgcGFyYW0xLCBEZXJpdmVkMSAmcGFyYW0yKSB7IGNvdXQgPDwgIjExXG4iOyB9CiAgICB2aXJ0dWFsIHZvaWQgVmlzaXQoRGVyaXZlZDEgJiBwYXJhbTEsIERlcml2ZWQyICZwYXJhbTIpIHsgY291dCA8PCAiMTJcbiI7IH0KICAgIHZpcnR1YWwgdm9pZCBWaXNpdChEZXJpdmVkMiAmIHBhcmFtMSwgRGVyaXZlZDEgJnBhcmFtMikgeyBjb3V0IDw8ICIyMVxuIjsgfQogICAgdmlydHVhbCB2b2lkIFZpc2l0KERlcml2ZWQyICYgcGFyYW0xLCBEZXJpdmVkMiAmcGFyYW0yKSB7IGNvdXQgPDwgIjIyXG4iOyB9Cn07CgpjbGFzcyBEZXJpdmVkMTogcHVibGljIEJhc2UKewpwdWJsaWM6CiAgIHZpcnR1YWwgdm9pZCBBY2NlcHQoVmlzaXRvciAmaVZpc2l0b3IsIEJhc2UmIHBhcmFtMSkgCiAgIHsgcGFyYW0xLkFjY2VwdChpVmlzaXRvciwgKnRoaXMpOyB9CiAgIHZpcnR1YWwgdm9pZCBBY2NlcHQoVmlzaXRvciAmaVZpc2l0b3IsIERlcml2ZWQxJiBwYXJhbTIpCiAgIHsgaVZpc2l0b3IuVmlzaXQoKnRoaXMsIHBhcmFtMik7IH0KICAgdmlydHVhbCB2b2lkIEFjY2VwdChWaXNpdG9yICZpVmlzaXRvciwgRGVyaXZlZDImIHBhcmFtMikKICAgeyBpVmlzaXRvci5WaXNpdCgqdGhpcywgcGFyYW0yKTsgfQp9OwpjbGFzcyBEZXJpdmVkMjogcHVibGljIEJhc2UKewpwdWJsaWM6CiAgIHZpcnR1YWwgdm9pZCBBY2NlcHQoVmlzaXRvciAmaVZpc2l0b3IsIEJhc2UmIHBhcmFtMSkgCiAgIHsgcGFyYW0xLkFjY2VwdChpVmlzaXRvciwgKnRoaXMpOyB9CiAgIHZpcnR1YWwgdm9pZCBBY2NlcHQoVmlzaXRvciAmaVZpc2l0b3IsIERlcml2ZWQxJiBwYXJhbTIpCiAgIHsgaVZpc2l0b3IuVmlzaXQoKnRoaXMsIHBhcmFtMik7IH0KICAgdmlydHVhbCB2b2lkIEFjY2VwdChWaXNpdG9yICZpVmlzaXRvciwgRGVyaXZlZDImIHBhcmFtMikKICAgeyBpVmlzaXRvci5WaXNpdCgqdGhpcywgcGFyYW0yKTsgfQp9OwoKdm9pZCBWaXNpdChWaXNpdG9yJiB2aXNpdG9yLCBCYXNlJiBwYXJhbTEsIEJhc2UmIHBhcmFtMikKewogICBwYXJhbTIuQWNjZXB0KHZpc2l0b3IsIHBhcmFtMSk7Cn0KCmludCBtYWluKCkgewogICBEZXJpdmVkMSBkMTsKICAgRGVyaXZlZDIgZDI7CiAgIFZpc2l0b3IgdjsKICAgVmlzaXQodiwgZDEsIGQxKTsKICAgVmlzaXQodiwgZDEsIGQyKTsKICAgVmlzaXQodiwgZDIsIGQxKTsKICAgVmlzaXQodiwgZDIsIGQyKTsKfQ==