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

C++ Function, take in enum and return a typedef class type to be used in template?

本文关键字:类型 typedef 接受 函数 enum 返回 C++      更新时间:2023-10-16

是否可以编写一个(内联?)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;

函数不能返回类型。你需要一个元函数:

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;

当然,这只适用于编译时(因为那是解析模板的时候)。

有几种方法。

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

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

首先,您可以执行一个神奇的切换,获取一个函子并使用运行时确定的enum值来调用它。有趣的是,最好先实现上述元函数解决方案。

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

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

神奇的切换技术并不是那么神奇。编写一个switch语句,并在每种情况下调用一个具有类型或编译时常数的模板函子。为了让它变得有趣,可以将开关的"body"作为模板参数,甚至可以使用一些元编程来通过嵌套的if或数组查找生成开关代码。不需要那些先进的技术。

使用模板并专门化:

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;