Edited at

scoped enumで配列のindexを指定する

More than 5 years have passed since last update.

C++03においてEnumでIndexを指定したい場合、リンク先のような方法で良さそうです。

http://d.hatena.ne.jp/Horiuchi_H/20100806/1281090492

c++11ではscoped enumがあるので結構違います。

あとは、range-based forとstd::arrayが便利。

c++03からの改善点は

● for文が楽に

● enumの列挙子名のスコープが狭くなり、列挙子名が重複しにくくなる

● 要素数をテンプレート引数から消せる

現状の問題点としては

● 列挙子に初期化子を指定すると大体バグる

● IndexEnum::SIZEをindexに与えるとバグる(エラー処理書けばいいけど、端折ってます)

● SIZEが列挙子にない場合コンパイルが通らない

● SIZEが最後以外にあるとバグる

● SIZE派、Size派、Count派云々で、争いが起こる

● unscoped enumでもscoped enumでも使える

そんなに深刻な問題は無さそうではあるが、気になる

c++XXでは

● 列挙子に初期化子を指定出来ないenum

● 列挙型の要素数を取得するなんらかの方法

この辺りが出来ると嬉しいかも。

constexperとかテンプレートテクニックでなんとかなりませんかね(適当)

あとinitializer_listを引数にしてArrayを初期化するのは良くわからなかったので、パスしてます。

追記

 そもそもinitializer_listでの初期化は、Enumの列挙子を並び替えたり、列挙子を減らすとバグる原因になるので実装しないで良いですね。

 コンパイラによっては(というかMSVCでは)autoに対応してないので、コンパイルが通らないっぽい。

その場合beginとendの戻り値の型を明示的に書けばよいです。

さらに追記

 関数の戻り値による型推論はC++1yからなので、記事のタグが怪しい感じですね。

#include <iostream>

#include <array>

template<typename T, typename Enum>
class EnumArray
{
public:
EnumArray(){}

EnumArray(T init)
{
Array.fill(init);
}

~EnumArray(){}

size_t size() const { return Array.size(); }
const T& operator[](const Enum& index) const { return Array[(int)index]; }
T& operator[](const Enum& index) { return Array[(int)index]; }

auto begin() const
{
return Array.begin();
}

auto end() const
{
return Array.end();
}

auto begin()
{
return Array.begin();
}

auto end()
{
return Array.end();
}

private:
std::array<T,(int)Enum::SIZE> Array;
};

enum class IndexEnum
{
A, B, C, D,
SIZE
};

int main(int, char**)
{
EnumArray<int,IndexEnum> intArray(0);
intArray[IndexEnum::A] = 1;
intArray[IndexEnum::C] = 3;

for( auto it:intArray)
{
std::cout << it << std::endl;
}

return 0;
}