是否可以编写一个(内联?)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;
答案 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
访问者),或者可能是virtual
或std::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;