I have this code:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector <bool> v;
cin >> v[0];
return 0;
}
Why can't I do that? The compiler won't compile that, but I have other variable types in the vector, it will work just fine. What's the problem with this?
It's because std::vector<bool>
is a specialization and doesn't act like a vector at all. This is widely recognized to be a major flaw in the Standard.
In order to save memory, vector<bool>
stores each element as a single bit. But bits aren't individually addressable, so operator[]
can't return a bool&
reference connected to a bit. Instead it returns vector<bool>::reference
... and cin
doesn't provide function overloads to deal with this.
(juanchopanza correctly points out that your vector didn't have an element zero. But even if it did via resize
or other mechanism, the fact that operator[]
doesn't return a reference still gets in the way.)
At the time you call v[0]
, the vector has zero size, so you are accessing out of bounds. This is undefined behaviour.
Furthermore, std::vector<bool>
is a specialization which has strange behaviour due to the fact that it does not hold individual bool
elements. Its operator[]
returns a kind of proxy object, the call to that operator may not do what you expect. It should be used with care, or not used at all.
You can solve the problem by reading a value into a local variable and then pushing it into the back of the vector, as in this working example (similar live demo here):
#include <vector>
#include <iostream>
int main()
{
std::vector<bool> v;
std::cout << std::boolalpha;
v.push_back(true);
std::cout << v[0] << std::endl;
bool b;
cin >> b;
v[0] = b;
std::cout << v[0] << std::endl;
}
This should work:
#include <iomanip>
...
bool a;
cin >> boolalpha >> a;
v.push_back(a);
(In addition to the problem mentioned by Ben Voigt, your current code isn't safe with types other than bool
because your vector is empty when you're accessing v[0]
.)