繁体   English   中英

C ++模板按枚举指定类型

[英]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::mapboost::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM