2013-07-10 57 views
1

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

我的直觉是,由于枚举类型的数量有限,应该有可能吗?

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

也许你想看看多态的类层次结构和工厂? –

+1

您应该解释您想解决的**真实**问题,而不是预期的解决方案。你所问的问题不能直接完成,但还有其他的东西可能适合这个问题(例如,从枚举映射到一个类型的特征) –

回答

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; 
+0

如果我错了,请原谅我,但是这种解决方案只有在类型在编译时已知?例如,如果枚举类型是在运行时获取的,它将无法工作? – user2570384

+1

@ user2570384:好的。这就是为什么他们称C++ *静态*键入。这不仅仅是它不起作用。如果您在编译时不知道枚举,那么整个问题就没有任何意义。 –

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

有几种方法。

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

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

首先,你可以做一个魔术开关,在那里你获得一个仿函数,并用运行时决定的enum值来调用它。有趣的是,最好通过首先实现上述的元函数解决方案来完成。

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

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

魔术开关技术并不是那么神奇。编写一个switch语句,并在每种情况下使用类型或编译时间常量调用模板函子。为了让它看起来很花哨,可以将交换机的“主体”作为模板参数,甚至可以使用一些元编程通过嵌套if或数组查找生成交换机代码。这些先进技术不是必需的。