Search code examples
c++pointersvectorconstantsoperator-precedence

Why is dereferenced element in const vector of int pointers mutable?


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.


Solution

  • 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.