gladilov-gleb

Double Dispatch

Nov 22nd, 2020
495
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Example program
  2. #include <iostream>
  3. #include <string>
  4. #include <stdexcept>
  5.  
  6. struct Visiter;
  7.  
  8. struct Op {
  9.     virtual void visit(Visiter*) = 0;
  10. };
  11.  
  12. struct Op0;
  13. struct Op1;
  14. struct Op2;
  15. struct Op3;
  16.  
  17. struct Visiter {
  18.     virtual void visit(Op const*) { throw std::invalid_argument("not supported"); }
  19.     virtual void visit(Op0 const*) = 0;
  20.     virtual void visit(Op1 const*) = 0;
  21.     virtual void visit(Op2 const*) = 0;
  22.     virtual void visit(Op3 const*) = 0;
  23. };
  24.  
  25. template<class T>
  26. struct Visitable : public Op {
  27.     void visit(Visiter* visiter) override {
  28.         visiter->visit(static_cast<T*>(this));
  29.     }
  30. };
  31.  
  32. struct Op0 : public Visitable<Op0> {};
  33. struct Op1 : public Visitable<Op1> {};
  34. struct Op2 : public Visitable<Op2> {};
  35. struct Op3 : public Visitable<Op3> {};
  36.  
  37. template<class T>
  38. struct SingleDoNothingVisiter : virtual Visiter {
  39.     using Visiter::visit;
  40.     void visit(T const*) override {}
  41. };
  42.  
  43. struct DoNothingVisiter
  44.     : public SingleDoNothingVisiter<Op0>
  45.     , public SingleDoNothingVisiter<Op1>
  46.     , public SingleDoNothingVisiter<Op2>
  47.     , public SingleDoNothingVisiter<Op3>
  48.     {};
  49.  
  50. struct PrecisionVisiter : public Visiter {
  51.     int precision;
  52.     void visit(Op0 const*) override {
  53.         precision = 0;
  54.     }
  55.     void visit(Op1 const*) override {
  56.         precision = 1;
  57.     }
  58.     void visit(Op2 const*) override {
  59.         precision = 2;
  60.     }
  61.     void visit(Op3 const*) override {
  62.         precision = 3;
  63.     }
  64. };
  65.    
  66.  
  67. #include <vector>
  68. int main()
  69. {
  70.     std::vector<Op*> v;
  71.     v.push_back(new Op0);
  72.     v.push_back(new Op1);
  73.     v.push_back(new Op2);
  74.     v.push_back(new Op3);
  75.  
  76.     try {  
  77.         PrecisionVisiter precisionVisiter;
  78.         for (const auto& op : v) {
  79.             op->visit(&precisionVisiter);
  80.             std::cout << "Precision = " << precisionVisiter.precision << std::endl;
  81.         }
  82.     } catch (std::invalid_argument const& error) {
  83.         std::cerr << error.what() << std::endl;
  84.     }
  85. }
  86.  
RAW Paste Data