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