-1

次のコードを検討してください。

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 値が期待されていることを知ってもらいたいのです。

4

2 に答える 2

1

列挙型は 2 バイトである必要があり、戻り値の型は列挙型参照でなければならないと言いtype()ます。

C++11 には、列挙型の基になる型を指定できる機能があります。

enum TestEnum : unsigned short
{
   TEST_ENUM_5 = 5
};

   TestEnum& type() { return mType; }
private:
   TestEnum mType;
于 2012-10-26T16:32:23.980 に答える
0

そのような使用法が必要な場合は、test.type() = TEST_ENUM_5;正しく実装してください。

   Test() { mType = TEST_ENUM_5; mVal = 1; }
   TestEnum& type() { return mType; }

private:
   TestEnum mType;

更新:「2 バイト」バージョン:

   Test() { mType = TEST_ENUM_5; mVal = 1; }
   uint16_t& type() { return mType; }

private:
   uint16_t mType;
于 2012-10-26T16:24:41.263 に答える