1

サイズが異なる可能性があるビットフィールドを含む構造体がいくつかあります。例:

struct BitfieldSmallBase {
    uint8_t a:2;
    uint8_t b:3;
    ....
}

struct BitfieldLargeBase {
    uint8_t a:4;
    uint8_t b:5;
    ....
}

一度にすべてのビットにアクセスする共用体:

template<typename T>
union Bitfield 
{
    T bits;
    uint8_t all;    // <-------------  Here is the problem

    bool operator & (Bitfield<T> x) const {
        return !!(all & x.all);
    }
    Bitfield<T> operator + (Bitfield<T> x) const {
        Bitfield<T> temp;
        temp.all = all + x.all;   //works, because I can assume no overflow will happen
        return temp;
    }
    ....
}

typedef Bitfield<BitfieldSmallBase> BitfieldSmall;
typedef Bitfield<BitfieldLargeBase> BitfieldLarge;

問題は次のとおりです。一部のビットフィールド基本クラスでは、uint8_t では不十分です。BitfieldSmall は uint8_t に適合しますが、BitfieldLarge は適合しません。データは可能な限り密にパックする必要があるため (後で SSE 命令によって処理されます)、常に uint16_t を使用することは問題外です。サイズがビットフィールドと同じ整数型で「all」フィールドを宣言する方法はありますか? または、ビット全体にアクセスする別の方法はありますか?

もちろん、テンプレートの使用を控えて、あらゆる種類のビットフィールドを明示的に宣言することもできますが、コードの繰り返しは避けたいと思います (演算子とメンバー関数のかなりのリストがあります)。

4

6 に答える 6

5

整数型をテンプレート パラメータにすることもできます。

template<typename T, typename U>
union Bitfield 
{
    T bits;
    U all;
}

typedef Bitfield<BitfieldSmallBase, uint8_t>  BitfieldSmall;
typedef Bitfield<BitfieldLargeBase, uint16_t> BitfieldLarge;
于 2009-10-01T12:04:04.263 に答える
1

使用している変数のビット幅は、コンパイラにマスキングとシフトを実行させる便利な方法ですが、メンバーの順序とパディングについて仮定することはできないという難しい方法を学びました。構造体。そのコンパイラに依存し、コンパイラは実際に順序を変更し、プロジェクト内の他のコードに依存します。

バイトを個別のフィールドとして扱いたい場合は、本当に難しい方法で行う必要があります。

于 2009-10-01T12:08:12.523 に答える
1

テンプレート メタプログラミングを使用して、BitfieldSmallBase、BitfieldLargeBase などから別の型にマップするテンプレート関数を定義できます。デフォルトでは uint8_t に、テンプレートの特殊化として BitfieldLargeBase の uint16_t にマップし、次のように使用します。

union Bitfield 
{
    T bits;
    typename F<T>::holder_type all;
};
于 2009-10-01T12:08:45.490 に答える
1

独自のローリングではなく、std::bitsetまたはboost::dynamic_bitsetを検討することをお勧めします。いずれにせよ、避けてstd::vector<bool>ください!

于 2009-10-01T12:09:20.840 に答える
0

必要なバイト数をテンプレート パラメーターの一部にします。

template <typename T, int S=1>
struct BitField 
{
   union
   {
      T bits;
      unsigned char bytes[S];
   };
};

typedef Bitfield<BitfieldSmallBase, 1>  BitfieldSmall;
typedef Bitfield<BitfieldLargeBase, 2> BitfieldLarge;
于 2009-10-01T21:31:50.380 に答える