1

列挙型を公開するクラスがあります。次のように、セッター関数で値の有効性を確認しようとしています。

enum abc 
{
   X,
   Y
};

int my_class::set_abc(abc value)
{
   if(static_cast<int>(value) > static_cast<int>(Y))
       return -1;
...
}

値が X より小さい場合にも同様のチェックがあります。

コンパイラがチェックを完全に削除していることがわかります。その理由を Google で検索したところ、C++ での整数変換のルールを説明している多くのページに出くわしましたが、列挙型から int への変換や有効性のチェックについての説明は見つかりませんでした。

これを達成する正しい方法は何ですか?

4

3 に答える 3

2

に対してテストするのは恣意的に思えるYので、いくつかの制限を追加します。これにより、最小値と最大値の間に要素を追加することもでき、順序を気にする必要はありません。

enum abc 
{
    ABC_MIN = 0,
    X,
    Y,
    ABC_MAX
};

int my_class::set_abc(abc value)
{
    assert(value > ABC_MIN && value < ABC_MAX);
{
于 2013-10-30T01:29:14.917 に答える
1

01が type の唯一の有効な値であるため、それabcよりも大きい値または小さい値を渡す人は誰でも、それを作成するために未定義の動作を既に呼び出しています。

C++ でコードを記述して、以前に UB を引き起こした条件を検出することは簡単ではありません。ご覧のとおり、コンパイラは、言語で許可または禁止されているものに基づいて最適化する傾向があります。

値をチェックしてから列挙型に変換する関数のオーバーロードを記述できますが、UB の呼び出しを回避するのは他の誰かの問題であるためint、オーバーロードをわざわざチェックする必要はありません。abc

または、列挙型に任意の値を追加することで、テストが冗長になるのを避けることができます。その後、コンパイラはそれを削除できません。

于 2013-10-30T01:29:38.520 に答える