2

これは密接に関連しています C++ 列挙型は署名されていますか、または署名されていませんか? . JavaMan の回答によると、 anenumはどちらsignedでもありませんunsigned。しかし、それは不可欠な昇格規則に従います。

私はライブラリを使用して作業しており、それらを使用enumsして、ほとんどunsignedのタイプを期待する他のクラス オブジェクトに渡します (unsigned intや などsize_t)。-Wsign-conversion正当な間違いを見つけようとして警告を有効にすると、言語のルールが原因で多数の誤検知が発生します。

ルールのようなものは、型の安全性を確保し、一般的な間違いを見つけるのが難しい状況を生み出します。static_castコード全体に散らばるようなものは避けたいので難しいです。

enums具体的なsignedまたは型に昇格するための言語の既定の動作をオーバーライドする方法はありますunsignedか? char( is signed または unsignedを指定する方法と同様です)。


関連して、このライブラリは 1990 年代に作成されたため、多くの古いコンパイラをサポートしています。解決策が C++03 に対応し、場合によってはそれ以前にも対処できれば素晴らしいことです。

C++03およびC++11の移動コンストラクターを保護する方法から? 、実際には、他の C++ 言語バリアントが有効になっていることを検出する信頼できる方法がないことはわかっています。-std=c++03と を使用した Clang 3.5 でのテスト中に、顔が平らになり-std=c++11ました。

4

2 に答える 2

2

C++03 列挙の基になる型は、その列挙子の値の範囲に依存し、int(C++98 [conv.prom] §4.5/2) ではなく、その基になる型に昇格します。

unsigned int処理できる値のみを追加することは、列挙型をそのまま動作させる汚い方法unsigned intです。

enum things {
    a, b, c,
    force_unsigned = -1U
};

デモ: http://coliru.stacked-crooked.com/a/d3ded108fb5a68bf

于 2015-07-06T07:14:42.770 に答える
1

あなたはあなた自身を転がすことができますenum class

struct safe_enum {
    enum type {
        value1, value2, value3
    };
    type value;

    operator unsigned int ()
        { return value; }
};

safe_enum foo = safe_enum::value1;
unsigned bar = safe_enum::value2;

残念ながら、これは C++03 列挙の「範囲外」の動作を失うため、このベスト プラクティス パターンはコードベースを壊します。また、 を に変更するenumclass、これが DLL として出荷されている場合、ABI が壊れます。

于 2015-07-06T07:06:50.793 に答える