Я думаю, вы путаете две вещи.
Класс bitset
хранит биты в компактных представлениях, например в массиве char
обычно 8 бит на char
(но YMMV на «экзотических» платформах).
Класс bitset::reference
предназначен для того, чтобы пользователи класса bitset
могли иметь объекты, подобные ссылкам, для битов, хранящихся в bitset
.
Поскольку обычные указатели и ссылки не имеют достаточной степени детализации, чтобы указывать на отдельные биты, хранящиеся в bitset
(их минимальная степень детализации равна char
), такой класс имитирует семантику ссылки на поддельные ссылки-подобные lvalue операции над битами. Это необходимо, в частности, для того, чтобы значение, возвращаемое operator[]
, работало «нормально» как l-значение (и, вероятно, составляет 99% от его «нормального» использования). В этом случае его можно рассматривать как «прокси-объект».
Такое поведение достигается путем перегрузки оператора присваивания и оператора преобразования в bool
; класс bitset::reference
, вероятно, будет инкапсулировать ссылку на родительский объект bitset
и смещение (байты + бит) ссылочного бита, которые используются такими операторами для извлечения и сохранения значения бита.
--- EDIT ---
На самом деле, реализация 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.)
*/