У меня есть фабрика, содержащая карту с именами объектов в качестве ключа и указателем для функции значения
template
static T* makeObj()
{
return new T();
}
using createFunction = std::function;
map types;
template
static void add(const std::string& name)
{
types.insert(name, makeObj);
}
Я хочу добавить дополнительную функцию для получения отфильтрованного списка типов (получить список унаследованных классов), примерно так:
template
static std::list getFilteredListOfTypes()
{
}
Вопрос в том, как это сделать.
Первая идея — создать карту со структурой в качестве значения и сохранить там объект соответствующего типа, я могу использовать < strong>dynamic_cast и проверяем все типы, но я сомневаюсь, что создание объекта — хорошая идея.
Другой способ — использовать std::is_base_of:template< class Base, class Derived >
struct is_base_of;
is_base_of принимает два типа: класс Base я могу получить из моего getFilteredListOfTypes, но как получить производный класс? Создайте объект и используйте decltype... но здесь снова создается объект.
Есть ли способ создать такую функцию фильтра без создания объектов?Это плохая идея — создать здесь объект? Разве это плохая идея — создавать объект для каждого элемента карты? Меня немного пугает ситуация, когда на фабрике будут сотни совсем не маленьких типов.
UPD
AppFactory.h:
class AppFactory
{
public:
template
static T* makeObj()
{
return new T();
}
using createFunction = std::function;
using registerMap = tsl::robin_map;
static registerMap& get();
template
static std::unique_ptr createUnique(const std::string& name)
{
return std::unique_ptr(create(name));
}
template
static std::shared_ptr createShared(const std::string& name)
{
return std::shared_ptr(create(name));
}
template
static T* create(const std::string& name)
{
if(get().contains(name))
{
return static_cast(get()[name]());
}
return nullptr;
}
template
static bool add(const std::string& name)
{
auto resultPair = get().insert_or_assign(name, makeObj);
return resultPair.second;
}
};
#define APPFACTORY_ADD(classname) \
namespace { static bool addName = AppFactory::add(#classname); }
AppFactory.cpp:
AppFactory::registerMap& AppFactory::get()
{
static AppFactory::registerMap map;
return map;
}
Использование фабрики:
...
APPFACTORY_ADD(SomeClass);
...
AppFactory::createUnique("SomeClass")
...
Подробнее здесь: https://stackoverflow.com/questions/786 ... he-factory