#include <iostream>
class Visitor;
class Element{
public :
virtual void Accept(Visitor&) = 0;
protected :
Element() {};
int num;
};
class Visitor {
public:
void Visit(Element* pe) { std::cout << getNum(pe) << '\n'; }
int getNum(Element* pe)
{
struct ElementNumAccessor : private Element
{
ElementNumAccessor(Element const& e) : Element(e) {}
int getNum() { return num; }
void Accept(Visitor&);
};
ElementNumAccessor ea(*pe);
return ea.getNum();
}
};
class ElementA : public Element{
public : ElementA() { num = 5; };
void Accept(Visitor& v) {v.Visit(this);}
};
class ElementB : public Element{
public : ElementB() { num = 6; };
void Accept(Visitor& v) {v.Visit(this);}
};
int main()
{
ElementA ea;
ElementB eb;
Visitor v;
ea.Accept(v);
eb.Accept(v);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgpjbGFzcyBWaXNpdG9yOwoKY2xhc3MgRWxlbWVudHsgCnB1YmxpYyA6IAogIHZpcnR1YWwgdm9pZCBBY2NlcHQoVmlzaXRvciYpID0gMDsKcHJvdGVjdGVkIDogCiAgRWxlbWVudCgpIHt9OyAgIAogIGludCBudW07Cn07CgpjbGFzcyBWaXNpdG9yIHsKcHVibGljOiAKICB2b2lkIFZpc2l0KEVsZW1lbnQqIHBlKSB7IHN0ZDo6Y291dCA8PCBnZXROdW0ocGUpIDw8ICdcbic7IH0KICBpbnQgZ2V0TnVtKEVsZW1lbnQqIHBlKQogIHsgCiAgICBzdHJ1Y3QgRWxlbWVudE51bUFjY2Vzc29yIDogcHJpdmF0ZSBFbGVtZW50CiAgICB7CiAgICAgIEVsZW1lbnROdW1BY2Nlc3NvcihFbGVtZW50IGNvbnN0JiBlKSA6IEVsZW1lbnQoZSkge30gICAKICAgICAgaW50IGdldE51bSgpIHsgcmV0dXJuIG51bTsgfQoKICAgICAgdm9pZCBBY2NlcHQoVmlzaXRvciYpOwogICAgfTsKICAgICAgCiAgICBFbGVtZW50TnVtQWNjZXNzb3IgZWEoKnBlKTsKICAgIHJldHVybiBlYS5nZXROdW0oKTsKICB9Cn07CgoKICAgICAgICAgY2xhc3MgRWxlbWVudEEgOiBwdWJsaWMgRWxlbWVudHsKICAgICAgICAgICAgICAgICBwdWJsaWMgOiBFbGVtZW50QSgpIHsgbnVtID0gNTsgfTsgCiAgICAgICAgICAgICAgICAgdm9pZCBBY2NlcHQoVmlzaXRvciYgdikge3YuVmlzaXQodGhpcyk7fQogICAgICAgICB9OwoKICAgICAgICAgY2xhc3MgRWxlbWVudEIgOiBwdWJsaWMgRWxlbWVudHsKICAgICAgICAgICAgICAgICBwdWJsaWMgOiBFbGVtZW50QigpIHsgbnVtID0gNjsgfTsgCiAgICAgICAgICAgICAgICAgdm9pZCBBY2NlcHQoVmlzaXRvciYgdikge3YuVmlzaXQodGhpcyk7fQogICAgICAgICB9OwoKICAgICAgICAgCmludCBtYWluKCkKewogICAgRWxlbWVudEEgZWE7CiAgICBFbGVtZW50QiBlYjsKICAgIFZpc2l0b3IgdjsKICAgIGVhLkFjY2VwdCh2KTsKICAgIGViLkFjY2VwdCh2KTsKICAgIAp9