6

http://www.cplusplus.com/reference/stl/bitset/から:

ほとんどの C++ 環境にはこのような小さな要素型は存在しないため、個々の要素は、要素を模倣する特別な参照としてアクセスされboolます。

正確には、このビット参照はどのように機能するのでしょうか?

私が考えることができる唯一の方法は、chars の静的配列を使用することですが、その場合、各インスタンスはそのインデックスを配列に格納する必要があります。各参照インスタンスのサイズは少なくとも asize_tであるため、ビットセットのコンパクトさが損なわれます。さらに、サイズ変更は遅くなる可能性があり、ビット操作は高速であると予想されます。

4

4 に答える 4

6

あなたは2つのことを混同していると思います。

このbitsetクラスは、ビットをコンパクトな表現 (たとえば、char配列) に格納します。通常は 1 つあたり 8 ビットcharです (ただし、「エキゾチックな」プラットフォームでは YMMV です)。

このbitset::referenceクラスは、クラスのユーザーが にbitset格納されているビットへの参照のようなオブジェクトを持つことができるようにするために提供されていbitsetます。

通常のポインターと参照には、に格納されている単一のビットを指すのに十分な粒度がないためbitset(最小粒度は ですchar)、そのようなクラスは、ビットに対する偽の参照のような左辺値操作への参照のセマンティックを模倣します。これは特に、によって返される値がoperator[]左辺値として「通常どおり」機能できるようにするために必要です (おそらく、その「通常の」使用の 99% を占めます)。この場合、「プロキシ オブジェクト」と見なすことができます。

この動作は、代入演算子と変換演算子をオーバーロードすることによって実現されboolます。このbitset::referenceクラスは、親オブジェクトへの参照と、参照されるビットのオフセット (バイト + ビット) をカプセル化するbitset可​​能性があります。これらは、ビットの値を取得および格納するためにそのような演算子によって使用されます。

- -編集 - -

実際には、g++ の実装bitset::referenceでは、バイトが格納されているメモリ ワードとそのワードのビット番号への直接のポインタがストアになります。ただし、これはパフォーマンスを向上させるための実装の詳細にすぎません。

ところで、ライブラリのソースで、何bitset::referenceが何で、何をするのかについて、非常に簡潔ですが明確な説明を見つけました。

  /**
   *  This encapsulates the concept of a single bit.  An instance of this
   *  class is a proxy for an actual bit; this way the individual bit
   *  operations are done as faster word-size bitwise instructions.
   *
   *  Most users will never need to use this class directly; conversions
   *  to and from bool are automatic and should be transparent.  Overloaded
   *  operators help to preserve the illusion.
   *
   *  (On a typical system, this <em>bit %reference</em> is 64
   *  times the size of an actual bit.  Ha.)
   */
于 2011-06-10T13:59:15.477 に答える
1

私は STL ソースを見ていませんが、Bitset 参照には実際のビットセットへのポインターとサイズ size_t のビット番号が含まれていると思います。参照は、ビットセット要素への参照を取得しようとしたときにのみ作成されます。

ビットセットの通常の使用では、参照が広範囲に使用される可能性はほとんどないため (使用されたとしても)、パフォーマンスの問題はあまり発生しないはずです。そして、概念的には型に似ていcharます。char は通常 8 ビットですが、char への「参照」を格納するにはポインターが必要なため、通常は 32 ビットまたは 64 ビットです。

于 2011-06-10T13:58:24.983 に答える
0

私は参照実装を見たことはありませんが、明らかに、参照を介して参照しているビットセットと、変更を担当するビットのインデックスを知っている必要があります。その後、残りのビットセット インターフェイスを使用して、必要な変更を行うことができます。これは非常に効率的です。ビットセットはサイズ変更できないことに注意してください。

于 2011-06-10T14:01:13.360 に答える
0

あなたが何を求めているのかよくわかりませんが、バイト内の個々のビットにアクセスする方法を教えてもらえます。これはおそらくビットセットが行うことです。次のコードは私自身のものではなく、Microsoft の仕様です (!)。

構造体を次のように作成します。

struct Byte
{
    bool bit1:1;
    bool bit2:1;
    bool bit3:1;
    bool bit4:1;
    bool bit5:1;
    bool bit6:1;
    bool bit7:1;
    bool bit8:1;
}

このコードの ':1' 部分はビットフィールドです。http://msdn.microsoft.com/en-us/library/ewwyfdbe(v=vs.80).aspx 変数が占めるビット数を定義するため、この構造体には 1 を占める 8 つのブール値があります。一口ずつ。したがって、合計で、'Byte' 構造体のサイズは 1 バイトになります。

char などの 1 バイトのデータがある場合、このデータを次のように Byte オブジェクトに格納できます。

char a = 'a';
Byte oneByte;
oneByte = *(Byte*)(&a);   // Get the address of a (a pointer, basically), cast this  
                          // char* pointer to a Byte*,
                          // then use the reference operator to store the data that 
                          // this points to in the variable oneByte.

これで、oneByte の bool メンバー変数にアクセスすることで、個々のビットにアクセス (および変更) できるようになりました。変更されたデータを char に再​​度格納するには、次のようにします。

char b;
b = *(char*)(&oneByte);   // Basically, this is the reverse of what you do to 
                          // store the char in a Byte.

この手法のソースを見つけて、クレジットが必要な場合はクレジットを与えるようにします。

また、繰り返しますが、この回答があなたにとって役立つかどうかは完全にはわかりません. あなたの質問は、「個々のビットへのアクセスは内部でどのように処理されますか?」と解釈しました。

于 2011-06-10T14:14:15.683 に答える