I am not sure the true meaning of const vector<int *> so I compiled the code below to get an idea but am now more confused.
vector<int *> v;
int x = 1, y = 2;
v.push_back(&x);
v.push_back(&y);
const vector<int *> w = v;
w[0] = &y; //failed. Element is a constant pointer?
*(w[0]) ++; //failed. Element pointer references to constant value?
If I had stopped here, I would have assumed that const vector<int *> is a vector of const int * const, but then I tried the following which clearly contradicted that assumption.
*(w[0]) += 3; //passed. Value not constant?
*(w[0]) = 20; //passed. Why...
Now *(w[0]) for reason unknown to me obviously treats ++ and += and assignment differently. I convinced myself that const vector only declares a constant object of the vector class and that the above results might depend on the actual implementation of the operator overloading of vector class. But I can't wrap my head around this. Can anyone help explain, please?
If it is relevant, I used g++ 4.2 on a Mac.
Why is dereferenced element in const vector of int pointers mutable?
For const vector<int *>, the element would be const pointer to non-const, i.e. int * const, so you can modify the object pointed by the pointer, but not the pointer itself.
According to Operator Precedence, postfix increment operator has higher precedence than operator*, so *(w[0]) ++; is equivalent to
* ((w[0]) ++); The increment on the pointer is performed at first, then it fails. w[0] = &y; is also trying to modify the pointer, so it fails too.
On the other hand, (*w[0]) ++; (i.e. increment on the pointee) would be fine. And the following statements are fine too, because they're both modifying the objects pointed by the pointer, not the pointers.
*(w[0]) += 3; //passed. *(w[0]) = 20; //passed.
It's a matter of operator precedence.
When you do *(w[0]) ++ you attempt to modify the pointer.
When you do *(w[0]) += 3 you modify the data pointed to by the pointer.
w is a const vector<int *>. The const qualifier is applied to the vector. Therefore, the corresponding const member function will be used for the operator[]:
const_reference operator[]( size_type pos ) const;
Since the vector is const-qualified and contains elements of type int * ( and not const int *), the type of the expression w[0] is int * const& (instead of const int *&). That is, it is a reference to a constant pointer to an int and not a reference to a pointer to a constant int: the constness is applied to the the pointer itself, not to the data being pointed.
By doing *(w[0]) += 3 you are not modifying the value of the pointer the vector returns (which is const), but the value this pointer is pointing to. Since this pointer is of type int * const (and not const int *), you can modify what it is pointing to, so it does work. However, doing w[0] = &y is performing an assignment on a constant pointer, so it does not compile.
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