C ++函数,接受枚举并返回要在模板中使用的typedef类类型?

时间:2013-07-10 22:15:10

标签: c++ templates

是否可以编写一个(内联?)C ++函数,我们接受枚举作为输入并返回可以在模板声明中使用的类类型?

我的直觉是,因为有一定数量的枚举类型,它应该是可能的吗?

enum MyEnumType { A, B, C };

class MyClassA { };
class MyCLassB { };
class MyClassB { };

template class<T>
class ATemplatedClass {
  // ...
};

NotSureWhatReturnType ConvertEnumToClassType(MyEnumType type) {
  switch (type) {
     case A: return MyClassA;
     case B: return MyClassB;
     case C: return MyClassC:
     default: throw;
  }
}

MyEnumType type = GottenSomewhere();

auto class_type = ConvertEnumToClassType(type);

ATemplatedClass<class_type> is_this_possible;

3 个答案:

答案 0 :(得分:3)

函数无法返回类型。您需要metafunction

template <MyEnumType>
struct ConvertEnumToClassType;

template <>
struct ConvertEnumToClassType<A> {
    typedef MyClassA type;
};

template <>
struct ConvertEnumToClassType<B> {
    typedef MyClassB type;
};

// … etc.

typedef ConvertEnumToClassType<A> class_type;

ATemplatedClass<class_type> is_this_possible;

当然这仅适用于编译时(因为那时解析了模板)。

答案 1 :(得分:2)

有几种方法。

首先,如果您在编译时知道enum,则可以创建一个以enum作为模板参数的元函数,并按预期返回tyoe。

如果不这样做,有几种方法。

首先,您可以进行魔术切换,在其中使用仿函数并使用运行时确定的enum值调用它。有趣的是,最好先实现上述元函数解决方案。

第二种方法是类型擦除。您返回一个外部统一的对象,但在其内部知道它具有特定类型。作为一个例子,boost::variant。现在访问该内部tyoe可能涉及上述解决方案(boost访问者),或者可能是virtualstd::function接口,它在内部存储不同的行为。

最后,您可以通过将运行时enum映射到编译时enum(而不是类型)来使用魔术切换技术,并使用第一种技术。

魔术开关技术并非一帆风顺。编写一个switch语句,并在每种情况下调用一个带有类型或编译时常量的模板函子。为了使它更好看,可以将开关的“主体”作为模板参数,甚至可以使用一些元编程通过嵌套的if或数组查找生成开关代码。那些先进的技术不是必需的。

答案 2 :(得分:1)

使用模板并专门化:

template <MyEnumType> struct ConvertEnum;

template <> struct ConvertEnum<A> { typedef MyClassA type; };
template <> struct ConvertEnum<B> { typedef MyClassB type; };
template <> struct ConvertEnum<C> { typedef MyClassC type; };

用法:

ConvertEnum<A>::type x;