ご存知のように、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
のいずれかの動作のようなクラスを知っていますか?
正しく動作しますか
いいえ。enum
sは、デフォルトで説明する方法で「ラップアラウンド」するようには設計されていません。
そして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;
}