++
値を本当に反復したい場合は、列挙型の演算子をオーバーロードすることをお勧めします。
Foo& operator++( Foo& f )
{
using UT = std::underlying_type< Foo >::type;
f = static_cast< Foo >( static_cast< UT >( f ) + 1 );
return f;
}
と使用
for (Foo foo = Foo::First; foo != Foo::Last; ++foo)
{
...
}
が許可されているかどうかの質問に答えるにはreinterpret_cast
、すべて 5.2.10/1 から始まります。
5.2.10 キャストの再解釈 [expr.reinterpret.cast]
1式の結果は、式を typereinterpret_cast<T>(v)
に変換した結果です。左辺値参照型または関数型への右辺値参照の場合、結果は左辺値です。オブジェクト型への右辺値参照の場合、結果は xvalue です。それ以外の場合、結果は prvalue であり、左辺値から右辺値 (4.1)、配列からポインター (4.2)、および関数からポインター (4.3) への標準変換が式に対して実行されます。を使用して明示的に実行できる変換を以下に示します。を使用して他の変換を明示的に実行することはできません。v
T
T
T
v
reinterpret_cast
reinterpret_cast
(私のものを強調)
参照を使用した再解釈は、5.2.10/11 に従ってポインターに基づいています。
11型「へのポインタ」の式がを使用して「へのポインタ」型に明示的に変換できる場合、型の glvalue 式はT1
「への参照」型にキャストできます。結果は、ソース glvalue と同じオブジェクトを参照しますが、指定された型を持ちます。[注:つまり、左辺値の場合、参照キャストは、組み込みのand演算子を使用した変換と同じ効果があります (同様に for )。—末尾の注] 一時ファイルは作成されず、コピーも作成されず、コンストラクター (12.1) または変換関数 (12.3) は呼び出されません。T2
T1
T2
reinterpret_cast
reinterpret_cast<T&>(x)
*reinterpret_cast<T*>(&x)
&
*
reinterpret_cast<T&&>(x)
これから質問を変換します:
reinterpret_cast<int8_t&>(foo)
これが合法かどうか:
*reinterpret_cast<int8_t*>(&foo)
次の目的地は 5.2.10/7 です。
7オブジェクト ポインターは、異なる型のオブジェクト ポインターに明示的に変換できます。v
型「ポインタへの」の prvalueが型「 cvT1
へのポインタ」に変換されるとき、結果は、との両方が標準レイアウト型 (3.9) であり、 の配置要件が の配置要件よりも厳密でない場合、またはいずれかの型がです。型「pointer to 」の prvalue を型「pointer to 」に変換し(ここで、 とはオブジェクト型であり、 の整列要件は の整列要件よりも厳密ではありません)、元の型に戻すと、元のポインター値が得られます。他のそのようなポインタ変換の結果は規定されていません。 T2
static_cast<
cv
T2*>(static_cast<
cv
void*>(v))
T1
T2
T2
T1
void
T1
T2
T1
T2
T2
T1
3.9/9int8_t
と列挙型の両方が標準のレイアウト型であるとすると、質問は次のように変換されます。
*static_cast<int8_t*>(static_cast<void*>(&foo))
これはあなたが運が悪いところです。static_cast
は 5.2.9 で定義されており、上記を合法とするものは何もありません。実際、5.2.9/5 は、それが違法であるという明確なヒントです。他の節は役に立ちません:
- 5.2.9/13 requires
T*
-> void*
-> T*
whereは同一でなければなりません ( cvT
を省略)
- 5.2.9/9 と 5.2.9/10 はポインタに関するものではなく、値に関するものです
- 5.2.9/11 はクラスとクラス階層についてです
- 5.2.9/12 はクラス メンバー ポインターに関するものです。
これからの私の結論は、あなたのコードは
reinterpret_cast<int8_t&>(foo)
は合法ではなく、その動作は標準で定義されていません。
また、上記の 5.2.9/9 および 5.2.9/10 は、最初の回答で提供したコードを合法にする責任があり、まだ上部にあることに注意してください。