6

来自http://www.cplusplus.com/reference/stl/bitset/

因为在大多数 C++ 环境中不存在这种小的元素类型,所以单个元素作为模仿元素的特殊引用进行访问bool

这个位参考究竟是如何工作的?

我能想到的唯一方法是使用chars 的静态数组,但是每个实例都需要将其索引存储在数组中。由于每个引用实例至少具有 a 的大小size_t,这将破坏位集的紧凑性。此外,调整大小可能会很慢,而位操作预计会很快。

4

4 回答 4

6

我认为你混淆了两件事。

该类bitset将位存储在一个紧凑的表示中,例如在一个char数组中,通常每个 8 位char(但在“外来”平台上是 YMMV)。

提供该类bitset::reference是为了允许bitset该类的用户对存储在bitset.

因为常规指针和引用没有足够的粒度来指向存储在 中的单个位bitset(它们的最小粒度为 char这尤其需要允许返回的值operator[]作为左值“正常”工作(并且它可能构成其“正常”使用的 99%)。在这种情况下,它可以被视为“代理对象”。

这种行为是通过重载赋值运算符和转换为bool运算符来实现的;该类bitset::reference可能会封装对父bitset对象的引用和被引用位的偏移量(字节+位),这些运算符用于检索和存储位的值。

- -编辑 - -

实际上,g++ 实现使bitset::referencestore 直接成为指向存储字节的内存字的指针,以及该字中的位数。然而,这只是提高其性能的一个实现细节。

顺便说一句,在库资源中,我发现了一个非常紧凑但清晰的解释,说明了什么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 的位数。仅当您尝试获取对 bitset 元素的引用时才会创建引用。

位集的正常使用不太可能广泛使用引用(如果有的话),因此不应该有太多的性能问题。而且,它在概念上类似于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 它们定义了一个变量需要占用多少位,所以在这个结构中,有 8 个布尔值占据 1咬一口。因此,“Byte”结构的总大小为 1 个字节。

现在如果你有一个字节的数据,比如一个 char,你可以将这个数据存储在一个 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 回答