#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