2017-06-17 9 views
11
これは非常にうまく機能

...ポインタを使用するまで、配列への参照が機能しないのはなぜですか?

int a[5] = {1,2,3,4,5}, int *p = a; 
int *& ref = p; 

しかし、なぜ動作しないのは?

int a[5] = {1,2,3,4,5}; 
int*& ref = a; 

両方apはポインタであり、同じ値(a[0]のアドレス)を有します。 ポインタ(p)を使用して配列を参照すると、非常にうまく動作します。

しかし、私はその配列a[]を直接参照すると動作しません...なぜですか?

答えて

25

aはポインタではなく、配列です。タイプはint[5]です。それができることはポインタint*への減衰です。これは最初のケースで起こります。だから、pへの参照はOKです。

今や第2のケースです。 aではなく、のポインタです。したがって、int[5]からint*に暗黙の変換が行われています。その変換の結果は価値があります。しかし、非const左辺参照(これはrefなのです)を右辺値にバインドすることはできません!したがって、コードはコンパイルに失敗します。

はここにアナロジーだ:

double a = 1.4; 
int& b = a; // implicit conversion from 'double' to `int` results in prvalue 
      // and you can't bind non-const lvalue refs to rvalues. 
0
int*& ref = a; 

int*はポインタ型ではなく、配列型です。だから、int[5]aにバインドされません。だから、

、配列名がアドレス定数、非const参照が定数を参照することはできませんですので、それは、正常に動作していますconst

int* const& ref = a; 

を使用しています。すでに回答されているものにに追加

+5

のような配列への参照を取得することができます配列名は、「アドレス定数」ではありません。これは、配列参照が生成する一時的な配列にconst参照をバインドすることができるためです。 – Quentin

+0

* static * arrayのアドレスはアドレス定数です。 * local *配列のアドレスはありません。 – AnT

9

、あなたが

int a[5]; 
int (&ref)[5] = a; 

Live

+0

私はちょうどこれを追加しようとしていましたが(以前は構文エラーをチェックしていました)。したがって、少なくとも私は追加することができます: 'g ++ -std = C++ 11'はこれを受け入れました。 (しかし私は過去にVS2013でも使ったことを覚えています) – Scheff

+4

@Scheffこれは新しいC++が必要ですか?本当に?私はこれが古代の構文だと思った。 [私にはうまくいく](https://godbolt.org/g/vsCiBz) –

+0

あなたは大丈夫です。私はちょうど私がちょうど(私が知っていると確信しているものではない)テストしたものを説明しました(私の年齢はひどく慎重になりました...) – Scheff

関連する問題