user2570384
user2570384

Reputation: 11

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

Is it possible to write an (inline?) C++ function, where we accept an enum as input and returns a class type which can be used in a template declaration?

My intuition is that since there are a finite number of enum types, it should be possible?

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;

Upvotes: 1

Views: 358

Answers (3)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275585

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.

Upvotes: 2

Konrad Rudolph
Konrad Rudolph

Reputation: 545648

Functions cannot return types. You need a 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;

Of course this only works at compile time (since that’s when templates are resolved).

Upvotes: 3

Kerrek SB
Kerrek SB

Reputation: 477150

Use a template and specialize:

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; };

Usage:

ConvertEnum<A>::type x;

Upvotes: 1

Related Questions