0

私は多かれ少なかれこのように見える列挙型を与えられました

enum foo{
X,
XandY,
XandZ,
XandYandZ,
none,
Y,
Z,
YandZ,
someSpecialCase,
anotherSpecialCase
};

パイプラインを通過するメッセージオブジェクトがいくつかあり、特定のステージでこのメッセージにXがあるかどうかが決まり、別のステージでYがあるかどうかが決まります。最終的に、メッセージにはこれらのラベルの1つを付ける必要があります。メッセージオブジェクトを設計しましたが、列挙型はすでに定義されています。列挙に与えられた数値を想定したくありません。そこで、hasX、hasYのように、さまざまな段階で個別に設定できるブールフラグを設定しました。ネストされたif-else句のレイヤーをいくつか書くよりも良い方法はありますか?

わかりやすくするために
編集しました。もう一度編集し、変数名を変更しました。

4

1 に答える 1

2

私が問題を正しく理解していれば、本質的にあなたが話しているのはマルチプレクサです。つまり、複数の情報ストリームを1つに結合します。これはルックアップテーブルを使用して簡単に実現でき、これの実装はあなた次第です。

さまざまな入力ストリームを組み合わせてキーオブジェクトにすることができます。以下にいくつかのコードを含めましたが、チェック/実行する時間がないため、逐語的ではなく擬似コードとして扱ってください。

地図を使う

struct MyKey
{
    MyKey( bool X, bool Y, bool Z, bool SC1, bool SC2 ) :
        X_(X), Y_(Y), Z_(Z), SC1_(SC1), SC2_(SC2) {}

    bool X_;
    bool Y_;
    bool Z_;
    bool SC1_;
    bool SC2_;
};

operator<()これを連想コンテナで使用するには、関数も必要です。次に、マップなどのマッピングコレクションを設定します。

typedef enum foo FooEnum;
std::map< MyKey, FooEnum > myMap;

このマップは、アプリケーションの起動時に設定し、以下のようにロードする必要があります。

myMap.insert( std::make_pair< MyKey, FooEnum >( MyKey(true,false,true,false,false), XandZ ) );

これはXとZが真であるだけであるXandZため、すべての順列にこれが必要です。

チェックを行うようになったら、必要なのは次のとおりです。

std::map< MyKey, FooEnum >::const_iterator it = myMap.find( MyKey(X,Y,Z,SC1,SC2) );
if ( it != myMap.end() )
{
    enum foo valueINeed = it.second;
    // ...

ベクトル/配列を使用する

これにはいくつかのバリエーションがあります。たとえば、入力ストリームの値をマスク内のビット(ここでは5ビット)として組み合わせ、32要素の配列またはベクトルを使用して、各順列を個別の要素にマップできます。

そうすれば、コンパイル時にコレクションを作成することもできます。テストする必要がありますが、おそらく少し速く実行されます。欠点は、コードがおそらくもう少し難解であるということですが、それでも文書化に対する法律はありません!

于 2012-08-03T14:52:15.057 に答える