我有一个我想存储在结构中的类树。我看到如何实现具有空或预定义构造函数的元素的结构,但我无法看到如何使用未预定义的构造函数参数签名来避开。所以说我们register diferent types into factory in a way that does not affect factory class directly。而我们的工厂是这样的:如何将参数传递给工厂元素构造函数?
Factory.hpp:
#include <unordered_map>
#include <string>
template<class BaseType, class BaseTypeCode>
class Factory {
public:
typedef BaseType * (*base_creator_fn)();
typedef std::unordered_map<BaseTypeCode, base_creator_fn> registry_map;
static registry_map & registry() {
static registry_map impl;
return impl;
}
static BaseType * instantiate(BaseTypeCode const & name) {
auto it = registry().find(name);
return it == registry().end() ? nullptr : (it->second)();
}
virtual ~Factory() = default;
};
template<class BaseClass, class BaseTypeCode>
struct Registrar {
Registrar(BaseTypeCode name, Factory<BaseClass>::base_creator_fn func) {
Factory<BaseClass>::registry()[name] = func;
}
};
所以现在的问题是:如何使一个typedef到typedef BaseType * (*base_creator_fn)(...);
,而不是目前的()
,其次如何在instantiate
转发论据将采取(BaseTypeCode const & name, ...)
,最后如何从构造函数中获取新的base_creator_fn,这些构造函数使用常量参数?
所以我希望在结束时得到这样的使用示例:
Example.hpp:
#include "Factory.hpp"
enum ExampleTypeCode { ExampleTypeCode_Simple = 1 };
class ExampleBase {
virtual ~ExampleBase(){}
};
class Example : public ExampleBase {
Example(int i) {}
virtual ~Example(){}
static Registrar<ExampleBase, ExampleTypeCode> registrar;
};
Example.cpp:
#include <boost/bind.hpp>
#include <boost/lambda.hpp>
#include "Example.hpp"
Registrar<Example, ExampleTypeCode> Example::registrar(ExampleTypeCode_Simple, boost::bind(boost::lambda::new_ptr<Example>, _firstVarArg));
Main.cpp
#include "Example.hpp"
int main() {
ExampleBase * p = Base::instantiate(ExampleTypeCode_Simple, 1);
}
我的主要编译目标是最新的GCC和可悲的Visual Studio 2012与最新的服务包 - 所以C++ 11子集是相当有限,但提出。
我认为你必须使用某种类型的擦除。你可以使用C++ 11,BTW吗? – Nawaz
顺便说一句,'Example'不是从'ExampleBase'派生的。另外,'Example.cpp'文件中似乎有错字。请先解决这些问题。 – Nawaz
@Nswaz:修正了一些错别字,VS2012主要的痛苦...所以一些C++ 11还没有完成它。 – DuckQueen