Long story short, I have
#include <vector>
template <class T>
class wrapped_vector {
private:
std::vector<T> elements;
public:
wrapped_vector() {
elements.resize(20);
}
T& operator[](int i) {
return elements[i];
}
const T& operator[](int i) const {
return elements[i];
}
};
int main(void) {
wrapped_vector<int> test_int;
test_int[0] = 1;
wrapped_vector<bool> test_bool;
test_bool[0] = true; // remove this line and it all compiles
}
and it gives me the compile error
test.cpp: In instantiation of ‘T& wrapped_vector<T>::operator[](int) [with T = bool]’:
test.cpp:28:13: required from here
test.cpp:15:34: error: invalid initialization of non-const reference of type ‘bool&’ from an rvalue of type ‘std::vector<bool, std::allocator<bool> >::reference {aka std::_Bit_reference}’
You got bitten by yet another side-effect of the "magic" std::vector<bool>
.
Since std::vector<bool>
doesn't actually store a contiguous array of bool
s, but packs them as a bitset, it cannot return a "real" reference to a bit in the middle of the bitset (since bits aren't directly addressable); for this reason, its operator[]
returns a proxy object that, overloading its operator=
, "fakes" a reference semantic.
The problem lies here: this proxy object is not a bool &
, so you cannot return it as such in your method.
The simplest way to solve would be something like this:
typename std::vector<T>::reference operator[](int i) {
return elements[i];
}
typename std::vector<T>::const_reference operator[](int i) const {
return elements[i];
}
that guarantees that you actually return whatever type std::vector
uses as "reference to T
" in its methods.
Also, you may want to use std::vector<T>::size_type
for indexes (mostly for coherency of your forwarder functions than anything else).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With