2016-05-13 16 views
3

ポインティングされた配列要素と配列要素の定数がそれぞれ異なるポインターと配列への奇妙なセマンティクスwrtバインディング参照があります。ポインタで、これは予想通り失敗:タイプT [N]のオブジェクトにT(&ref)[N]をバインドします。

int* p{}; 
const int*& p_ref{p}; 

non-const lvalue reference to type 'const int *' cannot bind to a value of unrelated type 'int *' 

&は、コンパイラを許可する前constを追加する、と-int型ポインタとポインタツーのconst int型は、2つの異なる種類があり、理にかなっ一時的な作品を制作するには効果がありますが、上記は変わりません。

しかし、私は配列に類似であるべきと思ったものを

int arr[5]{}; 
const int (&arr_ref)[5]{arr}; 

打ち鳴らすとgccは文句なし上記をコンパイルするが、なぜ両方ではないでしょうか?私はconst int[5]への非const参照をオブジェクトint[5]のオブジェクトにバインドします。これはなぜ許可されていますか?

更新:同様の問題は、スティーブン・C.デューハーストによってC++ Gotchasでガッチャの#32(82ページ)で説明されて

あなたの最初の例では
+0

も ​​'INT *のconst&P_REF {P}を考えます。'。 – Hurkyl

+0

@Hurkylそれは普通のconst refを非const変数にバインドしているだけでしょうか? –

+0

コンチネンタルコンプレックスの配置はこちらに関連しているようです:https://kuhllib.com/2012/01/17/continental-const-placement/ – Arvid

答えて

7

、それが許可された場合、constの正しさを破ることが可能であろう。

int *p{}; 
const int*& p_ref{p}; // pretend this is okay 
const int x = 10; 
p_ref = &x;   // storing the address of a const int in a const int*, okay 
*p = 5;    // Should be okay, because p is int*, not const int*, 
         // but oops, just modified a const value 

配列を参照することはできません(ポインタでないため)。配列への参照にはこの問題はありません。

ポインタへのポインタにも同様の問題があります。 non-const Tのアドレスをconst T*に格納することがよくあります。これは大丈夫ですので、の住所をconst T**に保存する必要があると考える傾向があります。しかし、それは、上記参考例と同様の問題が生じる:

int* p; 
const int** pp = &p; // forbidden, but pretend it's okay for now 
const int x = 10; 
*pp = &x;    // storing the address of a const int in a const int*, okay 
*p = 5;    // oops, modified a const int 
関連する問題