2

I just tested this piece of code.

vector<bool> v(5, true);
if(v.back())cout<<"====="<<endl;
auto b1 = v.back();
b1 = false;
cout<<&b1<<endl;
if(v.back())cout<<"*********"<<endl;

My questions are following:

  1. "*********" (no quotes) doesn't appear in the output, why the variable declared by auto is changing the bool vector v?
  2. I understand that vector<bool> is not a standard STL container, and addressing the element of it by &v[4] won't work(since you can not address the address of a bit), if b1 is declared by a reference to v.back(), why I can address b1 by &b1?
  3. In what cases auto has this kind of behavior? Does auto c1 = v.begin() and later doing c1 = (++v.begin()) will change v.begin()?
Allanqunzi
  • 3,230
  • 1
  • 26
  • 58
  • 3
    Be aware that `vector` is not a `vector`. – Deduplicator Dec 05 '14 at 02:23
  • 2
    `back()` return a reference, therefor I think auto will prefer declare it as reference. if you want to be sure test it with class and check if the copy constructor had been called. – SHR Dec 05 '14 at 02:23
  • 3
    @SHR: Uh... what? `auto x = whatever;` always means `x` *is not* a reference. – Deduplicator Dec 05 '14 at 02:24
  • `auto` follows the rules of template argument deduction. `I understand that vector is not a standard STL container` What is a "standard STL" container? It's either part of the standard library, or it's part of the STL. And it *is* a standard container, the specialization just happens to have different semantics. –  Dec 05 '14 at 02:25
  • possible duplicate of [Why is vector not a STL container?](http://stackoverflow.com/questions/17794569/why-is-vectorbool-not-a-stl-container) – DanielKO Dec 05 '14 at 02:31
  • 1
    Ok, I tested it with a class and the copy constructor was called, means the auto is NOT reference even though the function return reference. – SHR Dec 05 '14 at 02:40
  • 2
    @SHR Yes, `auto` will discard both `const` and `&`. `decltype(auto)` (C++14) preserves both - http://coliru.stacked-crooked.com/a/283d78b63e6627c3 – Praetorian Dec 05 '14 at 02:44

1 Answers1

13

std::vector<bool> is a failure in the standard library, a vector<T> which is not a container of Ts.

Thus, it has significantly different behavior from all other instantiations of vector.

The specific wart you stumbled over is that it's member-type reference is a proxy class representing a reference to a single bool.

Which means that auto, which never deduces as a reference, deduced as that proxy-class, will behave as if it was a reference.

&v[4] won't work for getting a pointer to the bool at index 4, because vector<bool> is not a container of bool and the index-operator also returns those proxy-classes.

Naturally, vector<bool> has really special iterators which allow iterating over the bit-set, so using iterators only has the handicap that dereferencing an iterator also returns a proxy.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118