To quote cppreference.com https://en.cppreference.com/w/cpp/container/vector_bool.html
std::vector<bool> is a possibly space-efficient specialization of std::vector for the type bool.
The manner in which std::vector<bool> is made space efficient (as well as whether it is optimized at all) is implementation defined. One potential optimization involves coalescing vector elements such that each element occupies a single bit instead of sizeof(bool) bytes.
If this implementation is provided, then when you access an element, a reference is not provided as would be the case for other vector types. Instead, it provides the value in an object created and returned by value. This object acts a bit like a reference, allowing you to access or modify the bool you requested, but it is not a reference.
Because it is not a reference (formally, because it is not an l-value), you cannot apply the address operator to get a non-const pointer. This means the following code will give a compiler error.
std::vector<bool> vectorBool(16); auto* ptr0 = &vectorBool[0]; //fails to compile auto* ptr1 = &(*vectorBool.begin()); //also fails to compile and is general to other conainers
You can use this to test at compile time whether your compiler is performing the operation. If you want something to do this check at runtime as well, then you can make use of concepts with something like the following
#include<vector> template<typename T> concept unoptimisedContainer = requires(T t, T::value_type* ptr) { ptr = &(*t.begin()); }; template<class T> constexpr bool isOptimisedContainer() requires (unoptimisedContainer<T>) { return false; } template<class T> constexpr bool isOptimisedContainer() requires (!unoptimisedContainer<T>) { return true; } constexpr bool hasBoolOptimisedVector() { return isOptimisedContainer<std::vector<bool>>(); } void testJustGrid() { constexpr bool optimisedBool = hasBoolOptimisedVector(); //should be true if bool optimisation is used, false otherwise constexpr bool optimisedInt = isOptimisedContainer<std::vector<int>>(); //should always be false as there's no optimised std::vector<int> }
std::vector<bool>is largely up to the compiler. It might not be optimized at all, or it might be optimized in an implementation-specific way. Generally, you find this out by consulting the documentation for your compiler. With GCC and other open-source toolchains, I suppose you could also consult the source code. But that not only takes more work, it may not be a very good idea, since source code documents only implementation, not contract.std::vector<bool>::reference_typeisbool &or something else. In the latter case, you have a proxy type, which should be allowed just for the "optimized" implementation.std::vector<bool>::referenceis required to be a proxy even if the implementation doesn't actually pack the bits.