fork download
  1. #include <iostream>
  2. #include <functional>
  3. #include <tuple>
  4.  
  5. enum class AnimalType
  6. {
  7. bird,
  8. mammal,
  9. lizard,
  10. fish,
  11. };
  12.  
  13. template<int LEGCOUNT, typename T>
  14. class AbstractAnimal
  15. {
  16. public:
  17. T printLegCount() { std::cout << LEGCOUNT << std::endl; return 0; }
  18. };
  19.  
  20. class Mammal : public AbstractAnimal<4, double>{};
  21. class Bird : public AbstractAnimal<2, int>{};
  22. class Lizard : public AbstractAnimal<4, float>{};
  23. class Fish : public AbstractAnimal<0, long long>{};
  24.  
  25. using AnimalTuple = std::tuple<Bird, Mammal, Lizard, Fish>; // Same order as enum AnimalType
  26.  
  27. template <typename T, typename F>
  28. std::function<void()> call_with_default(F&& f)
  29. {
  30. return [f]() {f(T{});};
  31. }
  32.  
  33. template <typename F, std::size_t...Is>
  34. void dispatch(AnimalType animalType, F&& f, std::index_sequence<Is...>)
  35. {
  36. std::function<void()> fs[] = {call_with_default<std::tuple_element_t<Is, AnimalTuple>>(f)...};
  37. fs[static_cast<int>(animalType)]();
  38. }
  39.  
  40. template <typename F>
  41. void dispatch(AnimalType animalType, F f)
  42. {
  43. dispatch(animalType, f, std::make_index_sequence<std::tuple_size<AnimalTuple>::value>{});
  44. }
  45.  
  46. void printLegCount(AnimalType animalType)
  47. {
  48. auto legCountPrinter = [](auto t) { t.printLegCount(); };
  49. dispatch(animalType, legCountPrinter);
  50. }
  51.  
  52. int main()
  53. {
  54. printLegCount(AnimalType::mammal);
  55. printLegCount(AnimalType::fish);
  56. }
Success #stdin #stdout 0s 3416KB
stdin
Standard input is empty
stdout
4
0