さよなら備忘録

「なにをいまさら」と言われそうな些細なことのメモがわり

enum class を範囲for文でループさせる

C++11で導入された enum class を static_cast で整数型にキャストしてむりくりfor文でループさせてるコードを見かけました。軽く調べたところ begin(), end(), operator*(), operator++()を定義すれば範囲for文で使えるようになるようです。

#include <iostream>

using namespace std;

enum class Dir { Top, Down, Left, Right, Max };

Dir begin(Dir) { return Dir::Top; }
Dir end(Dir) { return Dir::Max; }
Dir operator*(Dir dir) { return dir; }
Dir operator++(Dir& dir) {
    return dir = Dir(underlying_type<Dir>::type(dir) + 1);
}

ostream& operator<<(ostream& os, Dir dir) {
    switch (dir) {
        case Dir::Top:   return os << "Top";
        case Dir::Down:  return os << "Down";
        case Dir::Left:  return os << "Left";
        case Dir::Right: return os << "Right";
        default: return os;
    }
}

int main() {
    for (auto dir : Dir()) {
        cout << dir << endl;
    }
}

適用前のfor文は下のような感じでした。だいぶすっきりしましたね。

for (int i = static_cast<int>(Dir::Top); i < static_cast<int>(Dir::Max); ++i) {
  cout << static_cast<Dir>(i) << end;
}