[英]C++ template specify type by Enum
我面临一个问题:我想创建一个函数,该函数根据函数将接收的枚举来调用特定的模板类型构造函数。 我的意思是:
typedef ____ (Class<whatever>::*tabType)(int flag);
template<typename T>
static Class* Class<t>::createClassInstance(enum precision)
{
static const ___ createTab[] = {
Class<int>,
Class<double>
}
return (new createTab[precision](1));
}
有很多方法可以实现这种目的,但是听起来您想创建一个由enum
变量索引的工厂方法的数组(或映射)(每个类一个)。 每个调用相关的构造函数,并返回该类型的新对象。
当然,要使之有意义,所有类都必须派生自一个共同的基础。
如果枚举值作为函数参数是动态的,则必须使用调度表或switch / if-else。 请注意,您的伪代码并未明确说明要求。 假设您要定义的createInstance函数到底是什么,将如何调用它?
我会说,只需构造一个将enum
映射到工厂函数的std::map
( boost::function<>
)。 然后,您只需为每种类型添加一个条目,并带有相应的enum
。 实际构造工厂功能。 您可以为每个类都具有一些static Create()
函数并存储一个函数指针。 或者,您可以使用Boost.Lambda 构造函数/析构函数函子。 或者,您可以使用Boost.Bind构造函子,该函子包装需要一些参数的工厂函数。 这是一个例子:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/lambda/construct.hpp>
#include <map>
struct Base { };
struct Derived1 : public Base { };
struct Derived2 : public Base {
static Base* Create() { return new Derived2; };
};
struct Derived3 : public Base {
int value;
Derived3(int aValue) : value(aValue) { };
static Base* Create(int aValue) { return new Derived3(aValue); };
};
enum DerivedCreate { ClassDerived1, ClassDerived2, ClassDerived3 };
int main() {
std::map< DerivedCreate, boost::function< Base*() > constructor_map;
constructor_map[ClassDerived1] = boost::lambda::new_ptr<Derived1>();
constructor_map[ClassDerived2] = &Derived2::Create;
constructor_map[ClassDerived3] = boost::bind(&Derived3::Create, 42);
//now you can call any constructor as so:
Base* ptr = constructor_map[ClassDerived2]();
};
我可能在语法上犯了一些小错误,但是基本上您应该可以完成上述工作。 同样,您拥有多个类模板的事实也没有作用,一旦将它们实例化为具体的类(例如Class<int>
或Class<double>
),它们便与其他任何类一样,并且上述想法应保持有效。
扩展您的示例,类似以下内容的工作:
enum Prec {INT, DOUBLE};
struct Base
{
virtual ~Base () = 0 {}
};
template<typename T> struct Class : public Base
{
static Base* create (int flag) {return new Class<T> (flag);}
Class (int flag) {}
};
typedef Base* (*Creator) (int flag);
Base* createClassInstance (Prec prec)
{
static const Creator createTab[] = {
Class<int>::create,
Class<double>::create
};
return createTab[prec] (1);
}
int main (int argc, char* argv[])
{
Base* c = createClassInstance (DOUBLE);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.