fork download
  1. #include <unordered_map>
  2. #include <typeindex>
  3.  
  4. template <class Base>
  5. class clone_factory
  6. {
  7. public:
  8. using function_type = Base*(*)(Base&); // smart pointer/ggf. std::function und so sollten noch ergaenzt werden!
  9.  
  10. template <class Derived>
  11. void register_type(function_type func)
  12. {
  13. map_[typeid(Derived)] = func;
  14. }
  15.  
  16. Base* clone(Base &b) const
  17. {
  18. return map_.at(typeid(b))(b);
  19. }
  20.  
  21. private:
  22. std::unordered_map<std::type_index, function_type> map_;
  23. };
  24.  
  25. template <class Base, class Derived, typename FuncT>
  26. void register_types(clone_factory<Base> &clone, FuncT &&head)
  27. {
  28. clone.template register_type<Derived>(std::forward<FuncT>(head));
  29. }
  30.  
  31.  
  32. template <class Base, class Derived, class ... Deriveds, typename FuncT, typename ... FuncTs>
  33. void register_types(clone_factory<Base> &clone,
  34. FuncT &&head, FuncTs&&... functions) // Syntax geht bestimmt auch schoener.
  35. {
  36. clone.template register_type<Derived>(std::forward<FuncT>(head));
  37. register_types<Base, Deriveds...>(clone, std::forward<FuncTs>(functions)...);
  38. }
  39.  
  40. #include <iostream>
  41.  
  42. class base {public: virtual ~base() {}};
  43. class derived1 : public base {};
  44. class derived2 : public base {};
  45.  
  46. base* get_derived1(base &)
  47. {
  48. std::cout << "derived1\n";
  49. return nullptr;
  50. }
  51.  
  52. base* get_derived2(base &)
  53. {
  54. std::cout << "derived2\n";
  55. return nullptr;
  56. }
  57.  
  58. int main() try
  59. {
  60. clone_factory<base> factory;
  61. register_types<base, derived1, derived2>(factory, get_derived1, get_derived2);
  62. derived1 d1;
  63. derived2 d2;
  64. factory.clone(d1);
  65. factory.clone(d2);
  66. }
  67. catch(std::exception &ex)
  68. {
  69. std::cerr << "Error: " << ex.what() << '\n';
  70. }
  71.  
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
derived1
derived2