vector<bool>
std::vector<bool>
behaves similarly to std::vector
, but in order to be
space efficient, it:
- Does not necessarily store its elements as a contiguous array.
- Exposes class
std::vector<bool>::reference
as a method of accessing individual bits. In particular, objects of this class are returned byoperator[]
by value. - Does not use
std::allocator_traits::construct
to construct bit values. - Does not guarantee that different elements in the same container can be modified concurrently by different threads.
std::vector<bool> v{ true, true, false, true };
0b0000'0001 | 0b0000'0001 | 0b0000'0000 | 0b0000'0001 |
0b0000'1101 |
✔️
Member type | Definition |
---|---|
value_type |
T |
allocator_type |
Allocator |
size_type |
Unsigned integer type (usually std::size_t ) |
difference_type |
Signed integer type (usually std::ptrdiff_t ) |
reference |
Allocator::reference (until C++11)value_type& (since C++11) |
const_reference |
Allocator::const_reference (until C++11)const value_type& (since C++11) |
pointer |
Allocator::pointer (until C++11)std::allocator_traits<Allocator>::pointer (since C++11) |
const_pointer |
Allocator::const_pointer (until C++11)std::allocator_traits<Allocator>::const_pointer (since C++11) |
iterator |
LegacyRandomAccessIterator to value_type |
const_iterator |
LegacyRandomAccessIterator to const value_type |
reverse_iterator |
std::reverse_iterator<iterator> |
const_reverse_iterator |
std::reverse_iterator<const_iterator> |
Member type | Definition |
---|---|
value_type |
bool |
allocator_type |
Allocator |
size_type |
implementation-defined |
difference_type |
implementation-defined |
reference |
proxy class representing a reference to a single bool (class) |
const_reference |
bool |
pointer |
implementation-defined |
const_pointer |
implementation-defined |
iterator |
implementation-defined |
const_iterator |
implementation-defined |
reverse_iterator |
std::reverse_iterator<iterator> |
const_reverse_iterator |
std::reverse_iterator<const_iterator> |
template <class T>
void f(T& t)
{
typename T::value_type* p1 = &t[0];
typename T::value_type* p2 = &*t.begin();
// ... do something with *p1 and *p2 ...
}
What can we do about this?
Don't write code like this:
template <class T>
void f(T& t)
{
typename T::value_type* p1 = &t[0];
typename T::value_type* p2 = &*t.begin();
// ... do something with *p1 and *p2 ...
}