Специализация std::vector<bool> имеет метод flip(), который инвертирует все значения.
Подробное описание Ссылка на заголовок
Если бы std::vector<bool> для хранения значений выделял массив bool, то его размер в битах был бы равен N * sizeof(bool) * CHAR_BIT (а значит — как минимум N * CHAR_BIT), несмотря на то, что это значение можно закодировать одним битом. Однако стандарт позволяет реализациям применять специальные оптимизации для специализации std::vector<bool>. Так, реализация может хранить каждое значение bool, используя лишь один бит.
Небольшое отступление. Хотя
sizeof(bool)в большинстве случаев равен 1, стандарт этого не требует: он гарантирует только, чтоsizeof(bool) >= 1. Об этом явно сказано в стандарте. По умолчаниюsizeof(bool)равен 4 при компиляции под Darwin/PowerPC, и существует специальный флаг GCC-mone-byte-bool, который делаетsizeof(bool) == 1. В MSVC 4.2boolвообще был простоtypedefдляint.
Чтобы реализовать эту оптимизацию, можно аллоцировать массив из некоторых целочисленных значений, с которым процессору удобно работать (например, unsigned long), и работать с отдельными битами, используя битовые операции.
Если нужно инвертировать все хранимые значения, то простой проход по всем элементам и инвертирование каждого будет далеко не самым оптимальным решением, поскольку для вычисления каждого бита из хранимого unsigned long необходимо делать несколько битовых операций, а затем — ещё несколько, чтобы записать новое значение. Напрашивается более оптимальный подход — инвертировать сразу весь unsigned long. Таким образом, вместо прохода по всем значениям и инвертированию каждого мы проходим по всем хранимым unsigned long и инвертируем каждый, тем самым инвертируя CHAR_BIT * sizeof(unsigned long) подряд идущих бит нашего вектора. Для поддержки такого оптимизированного поведения, а также для того, чтобы интерфейс std::vector<bool> сильнее пересекался с std::bitset, был добавлен метод flip().
Разумеется, flip() имеет смысл только для специализации std::vector<bool>, поэтому другие специализации std::vector<T> не предоставляют этой функции-члена.
Пример Ссылка на заголовок
#include <cassert>
#include <vector>
int main() {
std::vector v{true, false};
v.flip();
assert((v == std::vector{false, true}));
}