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