web-dev-qa-db-fra.com

classe enum comme index de tableau

J'ai fait une énumération comme:

enum class KeyPressSurfaces {
    KEY_PRESS_SURFACE_DEFAULT,
    KEY_PRESS_SURFACE_UP,
    KEY_PRESS_SURFACE_DOWN,
    KEY_PRESS_SURFACE_LEFT,
    KEY_PRESS_SURFACE_RIGHT,
    KEY_PRESS_SURFACE_TOTAL
};

et plus tard, j'essaie de définir un tableau comme je l'ai tapé ci-dessous, mais j'ai reçu l'erreur, size of array 'KEY_PRESS_SURFACES' has non-integral type 'KeyPressSurfaces'

SDL_Surface*KEY_PRESS_SURFACES[KeyPressSurfaces::KEY_PRESS_SURFACE_TOTAL];

Je comprends bien l'erreur, mais je ne sais pas où déplacer le KeyPressSurfaces pour qualifier la constante dans l'énumération.

Je réalise également que je pourrais simplement utiliser un enum et non un enum class, mais je pense que cela devrait fonctionner et je veux apprendre à le faire.

Toute réponse/conseil est apprécié! Merci!

14
Hayden Piper

Portée enums (enum class) ne sont pas implicitement convertibles en entiers. Vous devez utiliser un static_cast:

SDL_Surface*KEY_PRESS_SURFACES[static_cast<int>(KeyPressSurfaces::KEY_PRESS_SURFACE_TOTAL)];
13
Simple

Vous pouvez convertir votre enum en int en utilisant la fonction de modèle et vous obtiendrez un code plus lisible:

#include <iostream>
#include <string>
#include <typeinfo>

using namespace std;

enum class KeyPressSurfaces: int {
    KEY_PRESS_SURFACE_DEFAULT,
    KEY_PRESS_SURFACE_UP,
    KEY_PRESS_SURFACE_DOWN,
    KEY_PRESS_SURFACE_LEFT,
    KEY_PRESS_SURFACE_RIGHT,
    KEY_PRESS_SURFACE_TOTAL
};

template <typename E>
constexpr typename std::underlying_type<E>::type to_underlying(E e) {
    return static_cast<typename std::underlying_type<E>::type>(e);
}


int main() {
    KeyPressSurfaces val = KeyPressSurfaces::KEY_PRESS_SURFACE_UP;
    int valInt = to_underlying(val);
    std::cout << valInt << std::endl;
    return 0;
}

Je trouve to_underlying fonction ici

11
gomons

Supprimez le mot clé class ou transtypez explicitement en type intégral.

4
knivil

En s'appuyant sur les autres réponses, une autre alternative est une classe simple basée sur un modèle qui enveloppe un tableau de style C. Avec l'exemple EnumArray ci-dessous, tout enum class avec un kMaxValue peut être utilisé comme index.

À mon avis, la lisibilité améliorée vaut l'introduction d'un modèle.

template <class IndexType, class ValueType>
class EnumArray {
 public:  
  ValueType& operator[](IndexType i) { 
    return array_[static_cast<int>(i)];
  }

  const ValueType& operator[](IndexType i) const {
    return array_[static_cast<int>(i)];
  }

  int size() const { return size_; }

 private:
  ValueType array_[static_cast<int>(IndexType::kMaxValue) + 1];

  int size_ = static_cast<int>(IndexType::kMaxValue) + 1;
}; 

enum class KeyPressSurfaces {
    KEY_PRESS_SURFACE_DEFAULT,
    KEY_PRESS_SURFACE_UP,
    KEY_PRESS_SURFACE_DOWN,
    KEY_PRESS_SURFACE_LEFT,
    KEY_PRESS_SURFACE_RIGHT,
    KEY_PRESS_SURFACE_TOTAL,
    kMaxValue = KEY_PRESS_SURFACE_TOTAL
};

int main() {
    EnumArray<KeyPressSurfaces, int> array;
    array[KeyPressSurfaces::KEY_PRESS_SURFACE_DEFAULT] = 5;
    std::cout << array[KeyPressSurfaces::KEY_PRESS_SURFACE_DEFAULT] << std::endl;
    return 0;
}
0
eric

Vous pouvez également remplacer votre array par un map, ce qui signifie également que vous pouvez vous débarrasser de KEY_PRESS_SURFACE_TOTAL:

enum class KeyPressSurfaces {
    KEY_PRESS_SURFACE_DEFAULT,
    KEY_PRESS_SURFACE_UP,
    KEY_PRESS_SURFACE_DOWN,
    KEY_PRESS_SURFACE_LEFT,
    KEY_PRESS_SURFACE_RIGHT
};

std::map<KeyPressSurfaces, SDL_Surface*> KEY_PRESS_SURFACES;
0
parsley72