web-dev-qa-db-ja.com

「列挙型クラス」のインクリメントとデクリメント

ご存知のように、C++ 03 enumは連続していない可能性があるため、C++ 03でのenumのインクリメントとデクリメントは違法です。しかし、C++ 11標準では、新しいenum class構造が導入されました。これは、ウィキペディアによると、単純な可算型に基づいて構築されていないため、より型安全性が高くなっています。だから今、列挙型の値の有界リストがある場合、次のようなものを書くことができますか?

enum class Colors { Black, Blue, White };
// ...
Colors color = Colors::White;
color++;

正しく機能しますか(たとえば、WhiteのインクリメントはBlackを返し、BlackのデクリメントはWhiteを返します)?

このようなコードを記述できない場合、この機能(正しいインおよびデクリメント)を提供するboostまたはQtのいずれかの動作のようなクラスを知っていますか?

21
Ivan Akulov

正しく動作しますか

いいえ。enumsは、デフォルトで説明する方法で「ラップアラウンド」するようには設計されていません。

そしてC++ 11のenum classは、C++ 03のenumについて説明したのと同じように、連続する値を保証しません。

ただし、特定の列挙型のラッピング動作を定義できます。 このソリューションは、説明した列挙型のように、値連続していることを前提としています

enum class Colors { Black, Blue, White, END_OF_LIST };

// Special behavior for ++Colors
Colors& operator++( Colors &c ) {
  using IntType = typename std::underlying_type<Colors>::type
  c = static_cast<Colors>( static_cast<IntType>(c) + 1 );
  if ( c == Colors::END_OF_LIST )
    c = static_cast<Colors>(0);
  return c;
}

// Special behavior for Colors++
Colors operator++( Colors &c, int ) {
  Colors result = c;
  ++c;
  return result;
}
25
Drew Dormann