방문자 디자인 패턴의 전통적인 구현방식은 이중 디스패치를 이용한다.
이중 디스패치를 구현할 때, 네이밍 관례
- 방문자의 멤버 함수는 visit() 이름을 사용
- 클래스 계층마다 구현되는 멤버 함수의 이름은 accept() 이름을 사용
struct Expression{
  virtual void accept(ExpressionVisitor* visitor)=0;
};
ExpressionVisitor는 추상 클래스로 여러 가지 방문자들(ExpressionPrinter, ExpressionEvaluator)의
베이스 클래스이다.
void accept(ExpressionVisitor* visitor) override {
  visitor->visit(this);   
}
Expression을 상속받는 모든 클래스(DoubleExpression, AdditionExpression)에 위와 같이
accept를 구현
struct ExpressionVisitor{
  virtual void visit(DoubleExpression* de)=0;
  virtual void visit(AdditionExpression* ae)=0;
};
struct ExpressionPrinter: ExpressionVisitor{
  ostringstream oss;
  string str() const { return oss.str(); }
  void visit(DoubleExpression* de) override;
  void visit(AdditionExpression* ae) override;
};
void ExpressionPrinter::visit(AdditionExpression* ae){
  oss<<"(";
  ae->left->accept(this);
  oss<<"+";
  ae->right->accept(this);
  oss<<")";
}
void main(void){
  auto e=new AdditionExpression{
    
  };
  
  ostringstream oss;
  ExpressionPrinter ep;
  ep.visit(e);
  cout<<ep.str()<<endl;   
}
하위 Expression 자체에서 멤버 함수 호출이 일어남.
방문자 추가하기
struct ExpressionEvaluator: ExpressionVisitor{
  double result;
  void visit(DoubleExpression* de) override;
  void visit(AdditionExpression* ae) override;
};
void ExpressionEvaluator::visit(DoubleExpression* de){
  result=de->value;
}
void ExpressionEvaluator::visit(AdditionExpression* ae){
  ae->left->accept(this);
  auto temp=result;
  ae->right->accept(this);
  result+=temp;
}   
auto e=new AdditionExpression{
  
}
ExpressionPrinter printer;
ExpressionEvaluator evaluator;
printer.visit(e);
evaluator.visit(e);
cout<<printer.str() <<" = "<<evaluator.result<<endl;