简体   繁体   English

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

[英]C++ template specify type by Enum

I'm facing a problem : I want to create a function which calls a specific template type constructor depending on a enum that the function will receive. 我面临一个问题:我想创建一个函数,该函数根据函数将接收的枚举来调用特定的模板类型构造函数。 By that i mean : 我的意思是:

  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));
  }

There are a number of ways of achieving this sort of thing, but it sounds like you want to create an array (or map) of factory methods (one for each class), indexed by the enum variable. 有很多方法可以实现这种目的,但是听起来您想创建一个由enum变量索引的工厂方法的数组(或映射)(每个类一个)。 Each one calls the relevant constructor, and returns a new object of that type. 每个调用相关的构造函数,并返回该类型的新对象。

Of course, for this to make any sense, all of the classes must derive from a common base. 当然,要使之有意义,所有类都必须派生自一个共同的基础。

If the enum value is dynamic as a function argument, you'll have to use either a dispatch table or switch/if-else. 如果枚举值作为函数参数是动态的,则必须使用调度表或switch / if-else。 Notice that your pseudo code does not clearly explain the requirement. 请注意,您的伪代码并未明确说明要求。 Say, what exactly the createInstance function you wish to define and how is it going to be called? 假设您要定义的createInstance函数到底是什么,将如何调用它?

I would say, just construct a std::map that maps the enum to a factory function ( boost::function<> ). 我会说,只需构造一个将enum映射到工厂函数的std::mapboost::function<> )。 Then you just add one entry for each type that you want, with its corresponding enum . 然后,您只需为每种类型添加一个条目,并带有相应的enum To actually construct the factory functions. 实际构造工厂功能。 You can either have some static Create() function for each class and store a function pointer. 您可以为每个类都具有一些static Create()函数并存储一个函数指针。 Or, you can use Boost.Lambda constructor/destructor functors. 或者,您可以使用Boost.Lambda 构造函数/析构函数函子。 Or, you can use Boost.Bind to construct functors that wrap a factory function that requires some number of parameters. 或者,您可以使用Boost.Bind构造函子,该函子包装需要一些参数的工厂函数。 Here is an example: 这是一个例子:

#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]();
};

I might have made some slight syntax mistakes, but basically you should be able make the above work. 我可能在语法上犯了一些小错误,但是基本上您应该可以完成上述工作。 Also, the fact that you have several class templates plays no role, once they are instantiated to a concrete class (like Class<int> or Class<double> ) they are just like any other class, and the above idea should remain valid. 同样,您拥有多个类模板的事实也没有作用,一旦将它们实例化为具体的类(例如Class<int>Class<double> ),它们便与其他任何类一样,并且上述想法应保持有效。

Extending your example, something like the following works: 扩展您的示例,类似以下内容的工作:

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