2

If I want a pointer to an element in a vector of vectors of int, I write:

vector<vector<int>> a (5);
int* p1 = a[4].data();

However, it doesn't work with a vector of vectors of bool (why?) when I write:

vector<vector<bool>> b(5);
bool* p2 = b[4].data();

The compiler outputs the following error message:

Semantic issue: Error: Cannot initialize a variable of type "bool*" with an rvalue of type "void".
Anselmo GPP
  • 271
  • 1
  • 17
  • 2
    https://en.cppreference.com/w/cpp/container/vector_bool – cplusplusrat Sep 07 '19 at 22:39
  • 1
    tl;dr - `std::vector` is special and weird. – Fureeish Sep 07 '19 at 22:41
  • 3
    [`std::vector::reference`](https://en.cppreference.com/w/cpp/container/vector_bool/reference) doesn't have a `data` method. – 0x499602D2 Sep 07 '19 at 22:41
  • It's highly unlikely you want to use vector at all. If you do want to take the addresses of things in the container, use a std::deque, or a std::vector.. –  Sep 07 '19 at 22:42
  • [Don't forget that pointers to `vector` elements can easily be invalidated.](https://stackoverflow.com/questions/6438086/iterator-invalidation-rules) – user4581301 Sep 07 '19 at 22:48
  • `int* p1 = a[4].data();` "Works" but probably not the way you think. `a[4].data()` is not pointer to an actual int because `a[4]` and all the other objects of the top vector are an empty vector of ints. to put something (43) into it you would use `std::a[4].push_back(42);` Then `*a[4].data() == 42` and you can also access it like so: `a[4][0]` – doug Sep 08 '19 at 02:10

1 Answers1

4

std::vector<bool> unfortunately is a specialization that may save space by using just a bit for each element. This is not guaranteed but can happen.

When this happens it means that using pointers to element is not possible (the minimum size of an object in C++ is one byte) and also a lot of other specifics of std::vector do not work for std::vector<bool>.

Just don't use it... if you need bit packing implement it yourself (at least you know what you get in a portable way) and if you don't care about the bit vs byte saving just use an std::vector<unsigned char> instead (that is a real std::vector).

std::vector<bool> specialization was basically a mistake of C++, it has no meaningful use. Doesn't provide any guaranteed advantage and may create problems in the future (for example even for code that currently doesn't need proper standard iterators now, may be the code will need to evolve into needing them, and if you used vector<bool> then you're doomed).

6502
  • 104,192
  • 14
  • 145
  • 251
  • It has plenty meaningful use if you don't need the features that aren't available as a result. Too much fearmongering here. – Lightness Races in Orbit Sep 08 '19 at 00:36
  • Or `struct bool_wrapper { bool value; };` and `std::vector` which requires a bit of packing and unpacking. (Puns intended.) – Eljay Sep 08 '19 at 01:04
  • I tend to agree on the "fearmongering" comment. `vector` is fine, as long as it is used within its defined limits. You can't blame the type for programmers who try to shoe-horn it into usage patterns it isn't suited for, and then complain when it doesn't work as expected. Trying to get the address of something that might be packed within a byte (the smallest addressable unit) is actually the problem, in this case. – Peter Sep 08 '19 at 02:24
  • @LightnessRacesinOrbit: the problem is that people don't expect `std::vector` to be something different from an `std::vector` of `bool`. If C++ wanted to provide a container of "bits" then it should have provided one (and guarantee/methods about how to handle it... for example do you know how to serialize efficiently an `std::vector`? ... you can't... you must iterate over all bits). `std::vector` is a mistake and should not been used (there have been even discussion about how to get rid of it, see http://www.gotw.ca/publications/N1211.pdf). – 6502 Sep 08 '19 at 08:20
  • @6502 I'm aware of all that, but the fact remains that if you _do_ know what `std::vector` is then you can make use of it just fine. It has plenty of "meaningful use". – Lightness Races in Orbit Sep 08 '19 at 12:53
  • @LightnessRacesinOrbit never seen it used, and I doubt anybody would who knows what it really is. Only usage I've seen by mistake from people expecting it to work like regular vector. – Slava Sep 08 '19 at 15:28
  • @Slava I use it on occasion – Lightness Races in Orbit Sep 09 '19 at 10:08