2017-09-08 4 views
29

const vector<int *>の真の意味が分からないので、以下のコードをコンパイルしてアイデアを得ましたが、今はもっと混乱しています。intポインタのconstベクトルの逆参照される要素が変更可能なのはなぜですか?

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? 

私はここに停止していた場合、私はconst vector<int *>const int * constのベクトルであると仮定しているだろうが、その後、私ははっきりとその仮定を否定し、次を試してみました。私には未知の理由のために今

*(w[0]) += 3; //passed. Value not constant? 
*(w[0]) = 20; //passed. Why... 

*(w[0])明らかに異なっ+++=と割り当てを扱います。 const vectorvectorクラスの定数オブジェクトのみを宣言し、上記の結果はvectorクラスの演算子オーバーロードの実際の実装に依存する可能性があると私は確信しました。しかし、私はこれの周りに私の頭を包むことはできません。誰でも説明を助けることができますか?

関連性がある場合は、Macでg ++ 4.2を使用しました。

+1

これは興味深いかもしれません。ポストをプリインクリメントに変更して、2番目の障害の例で何が起こるかを見てください。 '++ *(w [0]);'。 – WhozCraig

+1

私は混乱の大きな原因は、 '(* w [0])++;'の代わりに '*(w [0])++;'を書いていると思います。オペレータの優先順位は、時にはややこしいことがあります。 – Kat

答えて

33

intポインタのconstベクトルの逆参照される要素が可変であるのはなぜですか? const vector<int *>について

もしポインタが指すオブジェクトではなく、ポインタ自体を変更することができるように、要素は、constを非するconstポインタ、すなわちint * constあろう。

Operator Precedenceによれば、後置インクリメント演算子がoperator*より高い優先順位を有するので、*(w[0]) ++;

* ((w[0]) ++); 

に相当するポインタにインクリメントが最初に行われ、それは失敗します。 w[0] = &y;もポインタを変更しようとしているので、失敗します。

一方、(*w[0]) ++;(つまり、尖った部分の増加)は問題ありません。また、ポインタではなくポインターが指し示すオブジェクトを変更しているので、次のステートメントもうまくいきます。

*(w[0]) += 3; //passed. 
*(w[0]) = 20; //passed. 
9

operator precedenceです。

*(w[0]) ++を実行すると、ポインタを変更しようとしました。

*(w[0]) += 3を実行すると、ポインタが指すデータが変更されます。

5

wは、const vector<int *>である。 const修飾子がベクターに適用されます。したがって、対応するconstメンバ関数がoperator[]に使用する:

const_reference operator[](size_type pos) const;

ベクターは-qualified constあり、タイプint *(としないconst int *)の要素が含まれているので、式w[0]タイプはint * const&あります(const int *&の代わりに)。const性ポインタ自体にではなく、指摘されているデータに適用される:すなわち、intなく一定intへのポインタへ基準に一定のポインタへ参照です。あなたは(constである)ベクトルがを返すポインタの値を変更していない*(w[0]) += 3これにより

が、このポインタはを指している値。このポインタはタイプint * constconst int *ではない)なので、ポインタが指しているものを変更することができます。しかし、w[0] = &yを実行すると、定数ポインタに対する代入が実行されているため、コンパイルされません。

0

const vector<T>とし、その要素にはT const &、すなわちconst T &)とアクセスできます。この場合、Tint *なので、これはint * const &で、intを指すポインタへのconst参照です。ポインタは定数ですが、intはそうではありません。

ベクターの種類は、要素がint const * const &を介してアクセスされるであろう場合にvector<int const *>すなわちvector<const int*>)であることが必要であろう。

ボトムラインのconstはテンプレートでは推移的ですが、ポインタでは推移しません。テンプレートにポインタを置くと、両方の動作が少しずつ得られます。

関連する問題