31

|=強く型付けされた (スコープ化された)enum (C++11、GCC で)演算子をオーバーロードするにはどうすればよいですか?

厳密に型指定された列挙型のビットをテスト、設定、クリアしたい。なぜ強く型付けされたのですか?私の本はそれが良い習慣だと言っているからです。しかし、これは私がstatic_cast<int>どこにでも行かなければならないことを意味します。これを防ぐために|and演算子をオーバーロードしましたが、 enumで演算子&をオーバーロードする方法がわかりません。クラスの場合は、演算子の定義を classに入れるだけですが、列挙型の場合は構文的に機能しないようです。|=

これは私がこれまでに持っているものです:

enum class NumericType
{
    None                    = 0,

    PadWithZero             = 0x01,
    NegativeSign            = 0x02,
    PositiveSign            = 0x04,
    SpacePrefix             = 0x08
};

inline NumericType operator |(NumericType a, NumericType b)
{
    return static_cast<NumericType>(static_cast<int>(a) | static_cast<int>(b));
}

inline NumericType operator &(NumericType a, NumericType b)
{
    return static_cast<NumericType>(static_cast<int>(a) & static_cast<int>(b));
}

私がこれを行う理由: これは、厳密に型指定された C# で動作する方法です: 基になる型のフィールドを持つ構造体と、それに定義された一連の定数がある列挙型。ただし、列挙型の非表示フィールドに収まる任意の整数値を持つことができます。

そして、C++ 列挙型もまったく同じように機能するようです。どちらの言語でも、enum から int に、またはその逆にキャストする必要があります。ただし、C# ではビット演算子は既定でオーバーロードされますが、C++ ではそうではありません。

4

6 に答える 6

41
inline NumericType& operator |=(NumericType& a, NumericType b)
{
    return a= a |b;
}

これは機能しますか?コンパイルして実行: (Ideone)

#include <iostream>
using namespace std;

enum class NumericType
{
    None                    = 0,

    PadWithZero             = 0x01,
    NegativeSign            = 0x02,
    PositiveSign            = 0x04,
    SpacePrefix             = 0x08
};

inline NumericType operator |(NumericType a, NumericType b)
{
    return static_cast<NumericType>(static_cast<int>(a) | static_cast<int>(b));
}

inline NumericType operator &(NumericType a, NumericType b)
{
    return static_cast<NumericType>(static_cast<int>(a) & static_cast<int>(b));
}

inline NumericType& operator |=(NumericType& a, NumericType b)
{
    return a= a |b;
}

int main() {
    // your code goes here
    NumericType a=NumericType::PadWithZero;
    a|=NumericType::NegativeSign;
    cout << static_cast<int>(a) ;
    return 0;
}

3を印刷します。

于 2013-04-08T21:39:45.480 に答える
3

これは私にとってはうまくいくようです:

NumericType operator |= (NumericType &a, NumericType b) {
    unsigned ai = static_cast<unsigned>(a);
    unsigned bi = static_cast<unsigned>(b);
    ai |= bi;
    return a = static_cast<NumericType>(ai);
}

enumただし、ビットのコレクションのクラスを定義することを検討することもできます。

class NumericTypeFlags {
    unsigned flags_;
public:
    NumericTypeFlags () : flags_(0) {}
    NumericTypeFlags (NumericType t) : flags_(static_cast<unsigned>(t)) {}
    //...define your "bitwise" test/set operations
};

次に、|and&演算子をNumericTypeFlags代わりに return に変更します。

于 2013-04-08T22:06:42.693 に答える