fork download
  1. // generalisierte Klassen
  2.  
  3. template <typename T>
  4. struct single_visitor
  5. {
  6. virtual void visit(T&) = 0;
  7. };
  8.  
  9. template <typename ... Ts>
  10. struct generic_visitor : single_visitor<Ts>... {};
  11.  
  12. template <class Visitor>
  13. struct generic_acceptor
  14. {
  15. virtual void accept(Visitor&) = 0;
  16. };
  17.  
  18. #define OVERRIDE_ACCEPT \
  19. void accept(visitor &v) override \
  20. { \
  21. using this_t = typename std::decay<decltype(*this)>::type; \
  22. static_cast<single_visitor<this_t>&>(v).visit(*this); \
  23. }
  24.  
  25. // Nutzung
  26. #include <memory>
  27. #include <vector>
  28. #include <iostream>
  29.  
  30. struct concrete_node_1;
  31. struct concrete_node_2;
  32.  
  33. using visitor = generic_visitor<concrete_node_1, concrete_node_2>;
  34. using acceptor = generic_acceptor<visitor>;
  35.  
  36. struct node : acceptor {};
  37.  
  38. struct concrete_node_1 : node
  39. {
  40. OVERRIDE_ACCEPT
  41. };
  42.  
  43. struct concrete_node_2 : node
  44. {
  45. OVERRIDE_ACCEPT
  46. };
  47.  
  48. struct concrete_visitor_1 : visitor
  49. {
  50. void visit(concrete_node_1 &cn1) override { std::cout << "v1 cn1\n"; }
  51. void visit(concrete_node_2 &cn2) override { std::cout << "v1 cn2\n"; }
  52. };
  53.  
  54. struct concrete_visitor_2 : visitor
  55. {
  56. void visit(concrete_node_1 &cn1) override { std::cout << "v2 cn1\n"; }
  57. void visit(concrete_node_2 &cn2) override { std::cout << "v2 cn2\n"; }
  58. };
  59.  
  60. int main()
  61. {
  62. std::vector<std::shared_ptr<node>> nodes;
  63. nodes.push_back(std::make_shared<concrete_node_1>()); // 1
  64. nodes.push_back(std::make_shared<concrete_node_1>()); // 1
  65. nodes.push_back(std::make_shared<concrete_node_2>()); // 2
  66.  
  67. concrete_visitor_1 v1;
  68. for (auto const &n : nodes)
  69. n->accept(v1);
  70. concrete_visitor_2 v2;
  71. for (const auto &n : nodes)
  72. n->accept(v2);
  73. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
v1 cn1
v1 cn1
v1 cn2
v2 cn1
v2 cn1
v2 cn2