次のコードを検討してください。
enum TestEnum
{
TEST_ENUM_5 = 5
};
class Test
{
public:
Test() { mType = TEST_ENUM_5; mVal = 1; }
TestEnum& type() { return (TestEnum&)mType; }
private:
uint16_t mType;
uint16_t mVal;
};
int main( int argc, const char* argv[] )
{
Test test;
assert( test.type() == TEST_ENUM_5 );
}
プログラムは MSVC 2010 で正常にコンパイルされます - エラーや警告はありません。しかし、アサーションは失敗します。返される値は 5 ではなく、0x00010005 です。
つまり、返された列挙の値は 4 バイトの値として解釈されます。これには、次の short の内容が含まれます。コンパイラがこれを行っている理由がわかりました。参照は mType のアドレスへの参照であり、次の 4 バイトでレジスタがロードされています。
しかし、これはコンパイラにとって正しい動作ですか?
TestEnum& が 16 ビット量への参照であることを知っているべきではありませんか? または、それをしたくない場合は、警告するべきではありませんか?
それはさておき、私がやりたいのは、短い列挙を16ビット値に格納し、それへの参照を返すメソッドを持ち、それはそのtypedefとして型付けされることです。それが論理的に私が望むのは、次のことを可能にするインターフェースです。
test.type() = TEST_ENUM_5;
そして、TestEnum からの値のみが期待されることをコンパイル時に認識させます。さらに言えば、クラスのユーザーがそれを読んだときに、ここで TestEnum 値が期待されていることを知ってもらいたいのです。