Посмотрите, как это реализовано. STL строит значительно на шаблонах, и поэтому заголовки содержат код, который они делают.
например, посмотрите на stdC++ внедрение here.
также интересен, хотя не соответствует вектору бит stl, соответствует llvm :: BitVector от here.
суть llvm::BitVector
является вложенным классом называется reference
и подходящий оператор перегрузки, чтобы сделать BitVector
ведет себя похоже на vector
с некоторыми ограничениями. Код ниже - это упрощенный интерфейс, показывающий, как BitVector скрывает класс под названием reference
, чтобы реальная реализация почти вела себя как реальный массив bool без использования 1 байта для каждого значения.
class BitVector {
public:
class reference {
reference &operator=(reference t);
reference& operator=(bool t);
operator bool() const;
};
reference operator[](unsigned Idx);
bool operator[](unsigned Idx) const;
};
этот код здесь имеет хорошие свойства:
BitVector b(10, false); // size 10, default false
BitVector::reference &x = b[5]; // that's what really happens
bool y = b[5]; // implicitly converted to bool
assert(b[5] == false); // converted to bool
assert(b[6] == b[7]); // bool operator==(const reference &, const reference &);
b[5] = true; // assignment on reference
assert(b[5] == true); // and actually it does work.
Этот код на самом деле имеет недостаток, попробуйте запустить:
std::for_each(&b[5], &b[6], some_func); // address of reference not an iterator
не будет работать, потому что assert((&b[5] - &b[3]) == (5 - 3));
потерпит неудачу (в пределах llvm::BitVector
)
это очень простая версия с llvm. std::vector<bool>
имеет в нем также итераторы. Таким образом, вызов for(auto i = b.begin(), e = b.end(); i != e; ++i)
будет работать. а также std::vector<bool>::const_iterator
.
Однако есть еще ограничения в std::vector<bool>
, что заставляет его вести себя по-другому в некоторых случаях.
и @ Крис C++ 98. – Rapptz
@ Rapptz и C++ 03! – Casey
Это была ошибка дизайна в C++ 98, теперь сохраненная для совместимости. – Oktalist