Mohamed Elashri

The Great std::vector<bool> Betrayal

Alright, let me tell you about the biggest backstab in the C++ standard library. We know how std::vector<T> is supposed to be a dynamic array of T? Well, someone decided std::vector<bool> should be “special.”

Instead of storing actual bools, it packs bits. Sounds efficient, right? Except now everything breaks:

1std::vector<bool> flags = {true, false, true};
2bool* ptr = &flags[0];  // NOPE! Won't compile
3auto& ref = flags[1];   // NOPE! Can't have bool& to a bit

The “reference” you get back isn’t even a bool&, it’s some weird proxy object that pretends to be a bool:

1auto flag = flags[0];  // What's the type? bool? WRONG!
2// It's std::vector<bool>::reference, whatever that is

Here’s where it gets funny. You want a thread-safe container of flags?

1std::vector<bool> flags(1000);
2// Thread 1: flags[10] = true;
3// Thread 2: flags[11] = true;
4// RACE CONDITION! They might be in the same byte!

The real kicker? If you actually want a vector of bools that behaves like… you know… a vector of bools, you have to use std::vector<char> or std::deque<bool> like some kind of savage.

This isn’t some obscure corner case. It’s literally one of the most basic containers with one of the most basic types, and it’s been broken since 1998. The committee knows it’s broken. Everyone knows it’s broken. But here we are, more than 25 years later, still warning newcomers about the vector trap.

Sometimes I think C++ is just an elaborate hazing ritual.