Does the following program have undefined behavior?
#include
#include
struct Foo
{
const std::vector x;
};
int m
The above code does not invoke undefined behavior because the underlying data (int) is mutable. Let's look at a simpler example.
#include
struct IntPtr {
int* data;
};
int main() {
int a = 0;
const IntPtr p { &a };
*p.data = 10;
std::cout << a; // Prints 10
}
All of this is perfectly legal to do because making IntPtr
const results in data
being a constant pointer to an int, NOT a pointer to a constant int. We can modify the data that p.data
points to; we just can't modify p.data
itself.
const IntPtr p { &a };
*p.data = 10; // This is legal
int b;
p.data = &b; // This is illegal (can't modify const member)
So how does this example apply to std::vector
?
Let's add the ability to index into an IntPtr
:
class IntPtr {
int* data;
public:
IntPtr() = default;
IntPtr(int size) : data(new int[size]) {}
// Even though this is a const function we can return a mutable reference
// because the stuff data points to is still mutable.
int& operator[](int index) const {
return data[index];
}
};
int main() {
const IntPtr i(100);
i[1] = 10; // This is fine
};
Even though the IntPtr
is const, the underlying data is mutable because it's created by allocating an array of mutable ints. It's the same for std::vector
: the underlying data is still mutable, so it's safe to const_cast
it.