2011-09-05 4 views
8

2つの列挙型を変換するためにキャスト演算子をオーバーロードする方法はありますか?私は2つの列挙型間のオーバーロードキャスト演算子

enum devStatus 
{ 
    NOT_OPERATING, 
    INITIALISING, 
    DEGRADED, 
    NORMAL 
}; 

enum dataStatus 
{ 
    UNAVAILABLE = 1, 
    DEGRADED, 
    NORMAL 
} 

NOT_OPERATINGとUNAVAILABLEにマップを初期化を持っている私のコードで

。 DEGRADEDとNORMALはまっすぐに写像します。これらは外部インターフェイスによって固定されています。

私はdevStatusdataStatusの間で変換する方法を探していますとのようなものを書くことができるようにしたいと思います:

devStatus devSts; 
getDeviceStatus(&devSts); 
dataStatus dataSts = (dataStatus)devSts; 

私はこれらのクラスがあった場合、私はこれを行うにはdevStatus::operator dataStatus()を書くことができていることを知っています。列挙型のためにこれを行う方法はありますか?私は自由な関数にC++で dataStatus devStatus2dataStatus(const devStatus& desSts)

答えて

13

を持つことができ

、変換演算子がクラス、構造体、および共用体宣言の中だけを宣言することができます。型の外側で宣言することはできません(たとえば、operator +など)。列挙型宣言はインスタンスメンバーをサポートしないため、変換関数を使用する必要があります。そうすることで、呼び出しコードがより明確になります。次の例では、カスタム名前空間を使用して列挙関数と変換関数をスコープしています。

namespace TheirEnum { 
    enum Type { 
     Value1, 
     Value2 
    }; 
} 
namespace MyEnum { 
    enum Type { 
     Value1, 
     Value2 
    }; 

    TheirEnum::Type ToTheirEnum (Type e) { 
     switch (e) { 
     case Value1: return TheirEnum::Value1; 
     case Value2: return TheirEnum::Value2; 
     default: throw std::invalid_argument("e"); 
     } 
    } 
} 

// usage: 
TheirEnum::Type e = MyEnum::ToTheirEnum(MyEnum::Value1); 
+0

代わりに各列挙型と変換演算子のクラスを定義する利点と欠点は何ですか?下位の定型コード。上の部分では、外部の名前空間の周囲に浮動小数点の変換関数はありませんが、列挙型はすでにそこに浮かんでいると言われていますが。効率はコンパイラの最適化と同一でなければなりません。 –

+0

私はC++ enumの名前スコープが理想的ではないことに同意しますが、enum宣言と変換関数をネームスペースでラップすることで簡単に避けることができます。そのパスを下ると、is-a/has-a関係や、そのタイプにどの演算子を提供する必要があるかなど、論理的な問題が発生します。私は、そうすることがおそらく大部分の列挙では過度のことだと思います。 –

+0

答えをサンプルの名前空間宣言とサンプル使用法で更新しました。 –

関連する問題