2

特定の条件下でのみ特定のフィールドを含むデータ構造を生成する必要があります。通常、これは常に次のように変換されます。

struct MyStruct {
    int     alwaysHere;

#ifdef WHATEVER
    bool    mightBeHere;
#endif

    char    somethingElse;

#if SOME_CONSTANT > SOME_VALUE
    uint8_t alywasHereButDifferentSize;
#else
    uint16_t alywasHereButDifferentSize;
#endif
...
};

私の観点からすると、これは簡単に見にくくなり、読めなくなります。それらのフィールドを処理するコードについても話さずに、通常は ifdefs の下でも。

オーバーヘッドをまったく追加せずに同じ結果を達成するためのエレガントな方法を探していますが、コードははるかに読みやすくなっています。テンプレートの特殊化は少し過剰に思えますが、それが唯一の選択肢のように思えます。

C++11 は、この状況に対処するために何かを追加していますか?

任意の提案をいただければ幸いです。

4

4 に答える 4

5

2 番目のケースでは、通常、ハッカーを 1 か所に制限する typedef を好みます。

#if SOME_CONSTANT > SOME_VALUE
    typedef uint8_t always_type;
#else
    typedef uint16_t always_type;
#endif

その後、コードの残りの部分はalways_type全体で使用されます。

struct MyStruct {
    // ...
    always_type always_here_but_different_size;
    // ...
};

使用する場合:

typedef std::conditional<(SOME_CONSTANT > VALUE), uint8_t, uint16_t>::type always_type;

それも問題ありません。ここでのポイントは、必要な型を取得するために使用する構文についてではなく、必要な場所で使用できるように、通常はその型の名前を作成したいという事実です。

何かが存在するかどうかの状況については、少し言いにくいです。通常、そのようなことは、ビルド時に特定の機能を有効/無効にすることに関連します。もしそうなら、クラスは、有効化/無効化できる機能と、その他の機能の両方に関連する責任を負っているようです。それはおそらく単一責任の原則に違反しているように聞こえ、あまりまとまりがないかもしれません。その場合は、単に使用する構文よりも、設計全体のレベルで対処する方が適切な問題を示している可能性があります。

警告: 私はおそらく、明らかに最小限の証拠からかなりの部分を推定しています。おそらく、証拠が実際にサポートしている以上のものです.

于 2012-07-07T16:36:14.057 に答える
4

2 番目のケースは、

std::conditional<(SOME_CONSTANT > SOME_VALUE), uint8_t, uint16_t>::type
alywasHereButDifferentSize;

まずノーだと思います。

于 2012-07-07T15:22:08.693 に答える
1

ユニオン (http://www.cplusplus.com/doc/tutorial/other_data_types/) でこれが行われるのを見たことがありますが、自分で実装したことがないため、詳細についてはわかりません。マクロハッカーの 2 番目の部分の代わりに、次のようになります。

union {
  uint8_t alywasHereButDifferentSize;
  uint16_t alywasHereButDifferentSize;
}

参照するときは、どちらかの変数を参照する場合があります。

または、実行時にいずれかの型の変数に初期化する void * ポインターを作成することもできます。

于 2012-07-07T15:22:00.287 に答える
0

最初の場合:

template <bool>
struct implement_maybe_here
{};

template <>
struct implement_maybe_here<true>
{
    int maybe_here;
};

struct my_struct : implement_maybe_here<HAS_MAYBE_HERE>
{
    double always_here;
};

維持するのが難しく、変数を初期化するのが難しいので、私はこれを決してお勧めしませんmaybe_here(しかし、どのアプローチでも、これはとにかく混乱します)。

implement_maybe_here<false>メモリがゼロになることは保証されていませんが、多くのコンパイラはこの「空のベースの最適化」を実装しています。

std::conditional@ForEveRが示唆するように、2番目のものに使用してください。

于 2012-07-07T16:23:30.380 に答える