Mees de Vries Mees de Vries - 3 years ago 261
C++ Question

Why does the disjunction assignment operator |= not work with vectors of bools?

If I have a

vector<bool> vec_bool
then I cannot modify the contents of the vector using the
assignment operator. That is, the lines

vec_bool[0] |= true;
vec_bool[0] |= vec_bool[1];

give compiler errors, while the lines

bool a = false;
a |= true;
a |= vec_bool[0];
vec_bool[0] = vec_bool[0] | vec_bool[1];
vec_bool[0] = vec_bool[0] || vec_bool[1];

vector<int> vec_int(3);
vec_int[0] |= vec_int[1];

do not. What is the reason for this?

The error given (by gcc) is:

test.cpp:21:17: error: no match for ‘operator|=’ (operand types are ‘std::vector::reference {aka std::_Bit_reference}’ and ‘bool’)

Answer Source

The reference returned from operator[] of std::vector<bool> is not an alias for bool&, as it is for the primary specialization of std::vector. It is rather specified by the C++ standard as this:

// bit reference:
class reference {
  friend class vector;
  reference() noexcept;
  operator bool() const noexcept;
  reference& operator=(const bool x) noexcept;
  reference& operator=(const reference& x) noexcept;
  void flip() noexcept;     // flips the bit

And as you can see, there is no operator |= declared. So you can't apply it on the reference returned from vec_bool[0].

The reason that vec_bool[0] = vec_bool[0] | vec_bool[1]; works is that there are overloads above that facilitate it. operator bool() converts the two operands of the built-in | into bool values. And then the assignment operator of reference assigns the result back to vec_bool[0].

As specified by the C++ standard, std::vector<bool> isn't a particularly good abstraction, IMO.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download