web-dev-qa-db-ja.com

配列インデックスとしての列挙型クラス

私は列挙型を作りました:

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

その後、以下のように入力して配列を定義しようとしましたが、エラーsize of array 'KEY_PRESS_SURFACES' has non-integral type 'KeyPressSurfaces'が発生しました

SDL_Surface*KEY_PRESS_SURFACES[KeyPressSurfaces::KEY_PRESS_SURFACE_TOTAL];

エラーは問題ありませんが、KeyPressSurfacesを移動してenumの定数を修飾する場所がわかりません。

また、enum classではなくenumを使用するだけでよいことも理解していますが、これはうまくいくはずであり、その方法を学びたいと思っています。

どんな応答/アドバイスでもありがたいです!ありがとう!

14
Hayden Piper

スコープenums(enum class)は暗黙的に整数に変換できません。 static_castを使用する必要があります:

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

テンプレート関数を使用してenumintに変換すると、より読みやすいコードが得られます。

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

to_underlying関数 ここ

11
gomons

classキーワードを削除するか、整数型に明示的にキャストしてください。

4
knivil

他の応答に基づいて構築された別の代替手段は、Cスタイルの配列をラップする単純なテンプレートクラスです。以下のEnumArrayの例では、任意のenum class with kMaxValueをインデックスとして使用できます。

私の意見では、読みやすさの向上はテンプレートの導入に値します。

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

または、arraymapに置き換えることもできます。これは、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