#include <map>
#include<functional>
#include<string>

class Object {
 public:
  [[nodiscard]] virtual std::string ToString() const = 0;
  virtual ~Object() = default;
};

class Apple : public Object {
 public:
  explicit Apple(const std::string& class_id) {
    class_id_ = class_id;
  }
  [[nodiscard]] std::string ToString() const override {
    return class_id_;
  }

 private:
  std::string class_id_;
};

class List : public Object {
 public:
  explicit List(const std::string& class_id) {
    class_id_ = class_id;
  }
  [[nodiscard]] std::string ToString() const override {
    return class_id_;
  }

 private:
  std::string class_id_;
};

class YetAnotherIdentifier : public Object {
 public:
  explicit YetAnotherIdentifier(const std::string& class_id) {
    class_id_ = class_id;
  }
  [[nodiscard]] std::string ToString() const override {
    return class_id_;
  }

 private:
  std::string class_id_;
};

class Factory {
 public:
  Object* Create(const std::string& class_id) {
    return factory_[class_id]();
  }
  void Register(const std::string& class_id, Object* (*instance_creator)()) {
    factory_[class_id] = instance_creator;
  }
 private:
  std::map<std::string, std::function<Object* ()>> factory_ = {
      {"apple!", []() {return new Apple("apple!"); }},
      {"list", []() {return new List("list"); }},
      {"yet another identifier",
       []() {return new YetAnotherIdentifier("yet another identifier"); }}
  };
};