fork(10) download
  1. #include <unordered_map>
  2. #include <string>
  3. #include <iostream>
  4.  
  5. class Base
  6. {
  7. public:
  8. typedef std::unordered_map<std::string, void*> registry_map;
  9.  
  10. virtual ~Base() = default;
  11.  
  12. static registry_map & registry()
  13. {
  14. static registry_map impl;
  15. return impl;
  16. }
  17. template<typename ...T>
  18. static Base * instantiate(std::string const & name, T&&...args)
  19. {
  20. auto it = registry().find(name);
  21. if ( it == registry().end()) return 0;
  22. typedef Base* (*create_type)(T...);
  23. auto create_fun = reinterpret_cast<create_type>(it->second);
  24. return create_fun(args...);
  25. }
  26. virtual void f() = 0;
  27. };
  28.  
  29. struct Registrar
  30. {
  31. template<typename F>
  32. Registrar(std::string name, F func)
  33. {
  34. Base::registry()[name] = reinterpret_cast<void*>(func);
  35. }
  36. };
  37.  
  38. class DerivedExample : public Base
  39. {
  40. static Registrar registrar;
  41. public:
  42. static Base * create() { return new DerivedExample; }
  43. virtual void f() override { std::cout << "DerivedExample" << std::endl; }
  44. };
  45.  
  46. Registrar DerivedExample::registrar("DerivedExample", DerivedExample::create);
  47.  
  48. class AnotherExample : public Base
  49. {
  50. static Registrar registrar;
  51. int a;
  52. const char *b;
  53. public:
  54. AnotherExample(int a, const char *b) : a(a), b(b) {}
  55. static Base * create(int a, const char *b) { return new AnotherExample(a,b); }
  56. virtual void f() override { std::cout << "AnotherExample. a = " << a << ", b = " << b << std::endl; }
  57. };
  58.  
  59. Registrar AnotherExample::registrar("AnotherExample", AnotherExample::create);
  60.  
  61. int main()
  62. {
  63. Base * p = Base::instantiate("DerivedExample");
  64. Base * q = Base::instantiate("AnotherExample", 10, "Mahfuza");
  65. p->f();
  66. q->f();
  67.  
  68. delete p;
  69. delete q;
  70. }
  71.  
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
DerivedExample
AnotherExample. a = 10, b = Mahfuza