不同参数计数的结构方法列表
Fabric methods list for different arguments count
我有一个这样的工厂,它通过传递的模板类名T:实例化对象
template<class T>
class Factory0
{
public:
static void *Create(){ return new T(); }
};
template<class T, class Argument1>
class Factory1
{
public:
static void *Create( Argument1 &arg1 ){ return new T( arg1 ); }
};
我需要做这样的事情:
map<string[ClassName], &factory] _builder;
...
template<class T>
Add(){
if( T derived from BaseClass ) _builder[T] = &factory1::Create
else if( T derived from BaseClass ) _builder[T] = &factory0::Create;
}
template<class T>
Create() {
return _builder[T]( (factory0) ? <nothing> : <some_argument> );
}
这很难,原因有两个:
- 使用错误的参数调用create只能在运行时捕获,所以我们需要一些动态类型
- C++确实不喜欢强制转换函数指针。或者创建指向模板化函数的指针。或者通常使用函数指针执行任何复杂的操作
但这是可以做到的:
#include<string>
#include<map>
#include<iostream>
using namespace std;
struct returnable {
// Put some interesting virtual functions here
};
struct foo : public returnable {
foo() {
cout << "defaulFoo" << endl;
}
foo(int x) {
cout << "Foo:" << x << endl;
}
};
struct bar : public returnable {
bar(char a, char b){
cout << "bar:" << a << "," << b << endl;
}
};
template<typename... ARGS>
struct newmakerbase {
virtual returnable* make(ARGS... args) = 0;
};
template<typename OUT, typename... ARGS>
struct newmaker : public newmakerbase<ARGS...> {
virtual returnable* make(ARGS... args) {
return new OUT(args...);
}
};
// Boost might provide a neater version of this
int nextId = 0;
template<typename... T>
struct typeId {
static const int id;
};
template<typename... T>
const int typeId<T...>::id = nextId++;
map<string,void*> builders;
map<string,int> argtypes;
template<typename OUT, typename... ARGS>
void registerClas(string name) {
builders[name] = static_cast<void*>(new newmaker<OUT,ARGS...>());
argtypes[name] = typeId<ARGS...>::id;
}
template<typename... ARGS>
returnable* create(string name, ARGS... args) {
int argsgiven = typeId<ARGS...>::id;
if (argsgiven != argtypes[name]) {
// TODO: maybe throw an exception or something?
return NULL;
}
newmakerbase<ARGS...>* builder = static_cast<newmakerbase<ARGS...>*>(builders[name]);
return builder->make(args...);
}
main() {
registerClas<foo>("defaultFoo");
registerClas<foo,int>("foo");
registerClas<bar,char,char>("bar");
returnable* a = create("defaultFoo");
returnable* b = create("foo", 42);
returnable* c = create("foo", 'a', 'b'); // returns NULL
returnable* d = create("foo", 42.0); // also returns NULL
returnable* e = create("bar", 'c', 'd');
cout << a << " " << b << " " << c << " " << d << " " << e << endl;
}
相关文章:
- 通过方法访问结构
- 有什么方法可以遍历结构吗
- 没有为自己的结构调用列表推回方法
- 在 c++ 中拥有一组结构的正确方法是什么?
- 如何在方法中传递结构参数
- 对结构方法的未定义引用
- 不同的类或结构初始化方法之间的性能差异是什么?
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 我想直接在结构中插入,但没有一种方法可以正确避免填充问题
- 在C++中更改结构内部元素的方法?
- 学习数据结构和算法的简单方法
- 类方法 - 数据结构中 For 循环的运行时错误
- 如何从 node-ffi 调用 c++ 中以结构向量作为参数的方法?
- 哪一个是最好的方法类或结构?在 C++ 中
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 结构/方法不起作用
- 根据输入类型选择正确的结构方法
- C++结构方法语法
- 不同参数计数的结构方法列表
- 一个c++语法问题(一种结构方法)