I am writing an auto registering factory Factory
that registers a static method Create
from a wrapper BaseWrapper
around Base
class. Derived
class inherits from Base
class using BaseWrapper
. I used CRTP so that I don't need to add Create
function in every Derived
class.
I referred to this super neat tutorial -- http://www.nirfriedman.com/2018/04/29/unforgettable-factory/
The problem is that it only registers the Create
function if there is an user defined constructor of the derived class otherwise it does not and the assertion in the code fails. I am failing to understand why is it happening and how can I solve it without an user defined constructor.
(For brevity, I removed a lot of code)
#include <iostream>
#include <map>
#include <string>
struct Base {
virtual ~Base() = default;
};
using Func = std::function<Base*()>;
using FactoryMap = std::map<std::string, Func>;
struct Factory {
static FactoryMap& GetMap() {
static FactoryMap map;
return map;
}
static std::size_t GetSize() {
return GetMap().size();
}
static Func GetFunc(const std::string& name) {
return (HasFunc(name)) ? GetMap()[name] : nullptr;
};
static bool HasFunc(const std::string& name) {
auto& map = GetMap();
auto it = map.find(name);
return (it != std::end(map)) ? true : false;
};
static bool Register(const std::string & name, Func func) {
if (!HasFunc(name)) {
GetMap()[name] = func;
}
return true;
}
};
template <typename Derived>
struct BaseWrapper : public Base {
static Base* Create() {
return new Derived();
}
BaseWrapper() { (void) registered; };
static bool registered;
};
template <typename Derived>
bool BaseWrapper<Derived>::registered = Factory::Register(Derived::Name(), BaseWrapper<Derived>::Create);
struct Derived1 : public BaseWrapper<Derived1> {
static std::string Name() {
return "Derived1";
}
// only works if I uncomment this.
// Derived1(){};
};
int main() {
Base* base_ptr = Factory::HasFunc("Derived") ? Factory::GetFunc("Derived")() : nullptr;
assert(base_ptr != nullptr); // assertion fails
}
Aucun commentaire:
Enregistrer un commentaire