来自http://www.cplusplus.com/reference/stl/bitset/:
因为在大多数 C++ 环境中不存在这种小的元素类型,所以单个元素作为模仿元素的特殊引用进行访问
bool
。
这个位参考究竟是如何工作的?
我能想到的唯一方法是使用char
s 的静态数组,但是每个实例都需要将其索引存储在数组中。由于每个引用实例至少具有 a 的大小size_t
,这将破坏位集的紧凑性。此外,调整大小可能会很慢,而位操作预计会很快。
来自http://www.cplusplus.com/reference/stl/bitset/:
因为在大多数 C++ 环境中不存在这种小的元素类型,所以单个元素作为模仿元素的特殊引用进行访问
bool
。
这个位参考究竟是如何工作的?
我能想到的唯一方法是使用char
s 的静态数组,但是每个实例都需要将其索引存储在数组中。由于每个引用实例至少具有 a 的大小size_t
,这将破坏位集的紧凑性。此外,调整大小可能会很慢,而位操作预计会很快。
我认为你混淆了两件事。
该类bitset
将位存储在一个紧凑的表示中,例如在一个char
数组中,通常每个 8 位char
(但在“外来”平台上是 YMMV)。
提供该类bitset::reference
是为了允许bitset
该类的用户对存储在bitset
.
因为常规指针和引用没有足够的粒度来指向存储在 中的单个位bitset
(它们的最小粒度为 char
这尤其需要允许返回的值operator[]
作为左值“正常”工作(并且它可能构成其“正常”使用的 99%)。在这种情况下,它可以被视为“代理对象”。
这种行为是通过重载赋值运算符和转换为bool
运算符来实现的;该类bitset::reference
可能会封装对父bitset
对象的引用和被引用位的偏移量(字节+位),这些运算符用于检索和存储位的值。
- -编辑 - -
实际上,g++ 实现使bitset::reference
store 直接成为指向存储字节的内存字的指针,以及该字中的位数。然而,这只是提高其性能的一个实现细节。
顺便说一句,在库资源中,我发现了一个非常紧凑但清晰的解释,说明了什么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.)
*/
我没有查看 STL 源代码,但我希望 Bitset 引用包含指向实际位集的指针,以及大小为 size_t 的位数。仅当您尝试获取对 bitset 元素的引用时才会创建引用。
位集的正常使用不太可能广泛使用引用(如果有的话),因此不应该有太多的性能问题。而且,它在概念上类似于char
类型。char 通常是 8 位,但是要存储对 char 的“引用”需要一个指针,因此通常是 32 或 64 位。
我从未看过参考实现,但显然它必须知道它通过引用引用的位集,以及它负责更改的位的索引。然后它可以使用其余的位集接口进行所需的更改。这可能非常有效。注意位集不能调整大小。
我不太确定您在问什么,但我可以告诉您一种访问字节中各个位的方法,这可能是位集的作用。请注意,以下代码不是我自己的,而是 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.
我将尝试找到这种技术的来源,在应得的地方给予赞扬。
另外,我也不完全确定这个答案对你是否有用。我将您的问题解释为“如何在内部处理对单个位的访问?”。