mercredi 2 décembre 2015

Get the right templated class instantiation from an enum value

I have got this little problem, please have a look:

#include <iostream>

enum class AnimalType
{
   bird,
   mammal,
   lizard,
   fish,
};

template<int LEGCOUNT, typename T>
class AbstractAnimal
{
public:
   T printLegCount() { std::cout << LEGCOUNT << std::endl; return 0; }
protected:
};

class Mammal : public AbstractAnimal<4, double>{};
class Bird : public AbstractAnimal<2, int>{};
class Lizard : public AbstractAnimal<4, float>{};
class Fish : public AbstractAnimal<0, long long>{};


void printLegCount(AnimalType animalType)
{
   switch (animalType)
   {
      case AnimalType::bird: Bird{}.printLegCount(); break;
      case AnimalType::mammal: Mammal{}.printLegCount(); break;
      case AnimalType::lizard: Lizard{}.printLegCount(); break;
      case AnimalType::fish: Fish{}.printLegCount(); break;
   }
}

int main()
{
   AnimalType type = AnimalType::bird;
   printLegCount(type);
   return 0;
}

Actually the AnimalType enum in my code is huge (40 or more entries). The switch in printLegCount is also huge. And I have a few printLegCount-like functions to write with a switch case.

So I end up writting a long and terrible switch case each time I need to instantiate some classes. All I have on input is a runtime enum value (cannot be resolved at compile time). To one enum value corresponds one class. At first I wanted to write a vector or an array but my classes don't share any common ancestor. Actually I don't want a common ancestor because I cannot have any common methods in it, this is why printLegCount returns a T, to mimic my production code. The common ancestor would be an empty shell that I would have to downcast to the real type to use it.

Is there a way to write something like :

void printLegCount(AnimalType animalType)
{
   no_idea_how_to_write_it(animalType).printLegCount(); // h4lp plx
}

Instead of the huge switch case.

Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire