LoginSignup
4
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-06-09

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4