Jan Laloux Jan Laloux - 19 days ago 7
C++ Question

Class operator[] does not return a lhv

Consider this class:

#include <vector>
using namespace std;

template<typename T>
class Vector{
private:
size_t size_;
vector<T> items;

public:
Vector(){ size_ = 0; }
inline void clear(){ size_ = 0; }
inline void push_back( const T item ){
if( items.size() == size_ )
items.push_back( item );
else
items[size_] = item;
size_++;
}
inline const T& operator[](int i) const { return items[i]; }
inline T& operator[](int i) { return items[i]; }
};

int main(int argc, char *argv[]){
Vector<bool> vec;
vec.push_back( true );
if( vec[0] )
vec[0] = false;
}


When compiling with MSVS 2013 you get the following error for the non const operator[]:
error C2440: 'return' : cannot convert from 'std::_Vb_reference<std::_Wrap_alloc<std::allocator<char32_t>>>' to 'bool &'


Changing the return statement in
return (T&)(items[i]);
results in a warning
warning C4238: nonstandard extension used : class rvalue used as lvalue


The program runs (in debug mode) but the last statement does not change the value of
vec[0]
(as you should expect for a rhv).

What's wrong here?

Answer

Because std::vector<bool> is special, it's a space-efficient specialization of std::vector for the type bool. And operator[] won't return bool& or const bool&, but a proxy class representing a reference to a single bool.

Exposes class std::vector<bool>::reference as a method of accessing individual bits. In particular, objects of this class are returned by operator[] by value.