我有这个代码,这是一个适应从How to pass arguments to factory elements constructors?工作与智能指针。
#include <unordered_map>
#include <string>
#include <iostream>
#include <memory>
class Base;
class myFactory
{
public:
typedef std::unordered_map<std::string, void*> registry_map;
virtual ~myFactory() = default;
static registry_map & registry()
{
static registry_map impl;
return impl;
}
template<typename ...T>
static std::shared_ptr<Base> instantiate(std::string const & name, T&&...args)
{
auto it = registry().find(name);
if ( it == registry().end()) return 0;
typedef std::shared_ptr<Base> (*create_type)(T...);
auto create_fun = reinterpret_cast<create_type>(it->second);
return create_fun(args...);
}
template<typename F>
static bool sign(const std::string& name, F func)
{
registry()[name] = reinterpret_cast<void*>(func);
return true;
}
};
class Base: public myFactory
{
public:
virtual void f() = 0;
virtual ~Base() = default;
};
class DerivedExample : public Base
{
private:
static bool sign;
public:
DerivedExample(int a, int b){std::cout << a << b << std::endl;}
DerivedExample() = default;
static std::shared_ptr<Base> create() { return std::make_shared<DerivedExample>();}
static std::shared_ptr<Base> create(int a, int b) { return std::make_shared<DerivedExample>(a,b);}
virtual void f() override { std::cout << "DerivedExample" << std::endl; }
};
bool DerivedExample::sign = DerivedExample::myFactory::sign("DerivedExample", DerivedExample::create());
bool DerivedExample::sign = DerivedExample::myFactory::sign("DerivedExample", DerivedExample::create(int a, int b)); // redefinition
int main()
{
std::shared_ptr<Base> p1 = Base::instantiate("DerivedExample");
std::shared_ptr<Base> p2 = Base::instantiate("DerivedExample", 1, 2);
p1->f();
p2->f();
}
由于sign
boolean的重定义,这个实现不允许我为工厂注册2个构造函数。有没有办法修复代码,以便为同一个类注册多个create
函数?
最好的问候
2条答案
按热度按时间6kkfgxo01#
bool
sign
用于全局范围内的“自动”注册。您可以添加额外的变量:顺便说一句,注册的方式是错误的,特别是当涉及过载时。
Demo
y3bcpkx12#
一种修复代码的方法:
Live
但我不确定这是最好的设计。我更倾向于只为继承类注册一个(尽管上面的提议表明可以不这样做)。此外,变量签名是错误的,我通过将转发引用替换为按值传递来修复它,但这不一定是你想要做的。
[编辑]这是一个没有variadic的解决方案,只需要一个注册,遵循我在评论中的建议。
Live
你必须为每个你想要支持的构造函数创建一个派生的参数类型。你可以根据你真正想要达到的目标来避免重复。