1

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

3 回答 3

3

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

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;

当然,这只在编译时有效(因为那是模板被解析的时候)。

于 2013-07-10T22:19:23.380 回答
2

There are a few approaches.

First, if you know the enum at compile time, you can create a metafunction that takes the enum as a template argument and return the tyoe as expected.

If you do not, there are a few approaches.

First, you can do a magic switch, where you take a functor and invoke it with the runtime-determined enum value. Amusingly this is best done by first implementing the above metafunction solution.

A second approach is type erasure. You return an object that is externally uniform, but inside it knows that it has a particular type. As an exampke, boost::variant. Now accessing that internal tyoe can involve the above solution (boost visitor like), or maybe a virtual or std::function interface that stores the different behavior internally.

Finally, you can use the magic switch technique by mapping the runtime enum into a compile time enum (instead of a type) and just use the fist technique.

The magic switch technique is not all that magic. Write a switch statement and in each case invoke a template functor with a type or compile time constant. To make it fancy, take the 'body' of the switch as a template parameter, and maybe even use some metaprogramming to generate the switch code via nested if or an array lookup. Those advanced techniques are not required.

于 2013-07-10T23:13:20.393 回答
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;
于 2013-07-10T22:17:47.380 回答