Crowds Control

Artificially intelligent, virtually real

std::vector<bool> is NOT a std::vector containing bools

15 February 2010 // development // reaching for Disqus...

Everything in the title, but let me explain… Lately I’ve spent a lot of time trying to make a serialization/deserialization work with the huge piece of software I’m working on at Golaem. Anyway I came across a strange compiler error when trying to deserialize a std::vector<bool>. Here’s what our serialization engine is like:

 1 template<T>
 2 void read(std::vector<T>& myVector, Bitstream myStream)
 3 {
 4   unsigned int size;
 5   read(size,myStream);
 6   vector.resize(size);
 7   for (unsigned int i = 0 ; i < size ; i++)
 8   {
 9     read(vector[i],stream);
10   }
11 }
12 void read(bool& myBool, Bitstream stream)
13 {
14   ...
15 }
16 template<T>
17 void write(const std::vector<T>& myVector, Bitstream myStream)
18 {
19   unsigned int size;
20   write((unsigned int)myVector.size(),myStream);
21   for (unsigned int i = 0 ; i < myVector.size() ; i++)
22   {
23     write(vector[i],stream);
24   }
25 }
26 void write(const bool& myBool, Bitstream stream)
27 {
28   ...
29 }

The serialization worked ok, but when trying the deserialization I got a cryptic compiler error:

impossible to convert from std::_Vb_reference<_Sizet,_Difft,_MycontTy> to bool &

WTF ? This code worked perfectly for doubles, ints and other basic types bools should be fine no ? After a quick google and follow links session I stopped on the cplusplus.com reference page of the std::vector. You should go and read this page completly, yep now ! I give you a few seconds… OK you should’ve finished now, and yeah, you read well, std::vector<bool> is a template specialization of std::vector<T> and it does not have the the same properties: std::vector<bool>::operator[] doesn’t returns a reference to a bool but a specially defined type. I love C++ and especially the STL… Yes, in most cases it’s transparent because this type defines a transtyping operator to bool. Yes, it is designed to save space as each element of a std::vector<bool> takes only 1 bit. But, it is inconsistent (std::deque<bool> is a std::deque of bools), opposed to the basic principles of c++ templates, and, apparently not normalized (see this open letter wrote by Herb Sutter the day i turned 15). Another good joke from our pals at C++ ISO committee…