fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <map>
  4. #include <memory>
  5.  
  6. struct One;
  7. struct Two;
  8. struct Three;
  9.  
  10. struct Number {
  11. virtual ~Number() {}
  12. virtual void f() = 0;
  13.  
  14. static Number* getByName(const std::string &name) {
  15. static const std::map<std::string, std::function<Number*()>> factories = {
  16. register_helper<One>(),
  17. register_helper<Two>(),
  18. register_helper<Three>()
  19. };
  20.  
  21. auto it = factories.find(name);
  22. if (it == factories.end()) {
  23. return nullptr;
  24. } else {
  25. return it->second();
  26. }
  27. }
  28. private:
  29. template <typename T>
  30. static std::pair<std::string, std::function<Number*()>> register_helper()
  31. {
  32. return { T::name, []() { return new T{}; }};
  33. }
  34.  
  35. };
  36.  
  37. struct One : Number {
  38. virtual void f() override { std::cout << "ONE" << std::endl; }
  39. const static std::string name;
  40. };
  41.  
  42. struct Two : Number {
  43. virtual void f() override { std::cout << "TWO" << std::endl; }
  44. const static std::string name;
  45. };
  46.  
  47. struct Three : Number {
  48. virtual void f() override { std::cout << "THREE" << std::endl; }
  49. const static std::string name;
  50. };
  51.  
  52. const std::string One::name = "one";
  53. const std::string Two::name = "two";
  54. const std::string Three::name = "three";
  55.  
  56. int main() {
  57. std::unique_ptr<Number> two(Number::getByName("two"));
  58. two->f();
  59. }
  60.  
Success #stdin #stdout 0s 3464KB
stdin
Standard input is empty
stdout
TWO