web-dev-qa-db-ja.com

定数参照とは何ですか? (定数への参照ではありません)

かなり理論的な質問です...なぜ定数参照は定数ポインタと同じように振る舞わず、実際にそれらが指しているオブジェクトを変更できますか?彼らは本当に別の単純な変数宣言のように見えます。なぜそれらを使用するのですか?これは、エラーなしでコンパイルして実行する短い例です。

int main (){
    int i=0;
    int y=1;    
    int&const icr=i;
    icr=y;          // Can change the object it is pointing to so it's not like a const pointer...
    icr=99;         // Can assign another value but the value is not assigned to y...
    int x=9;
    icr=x;
    cout<<"icr: "<<icr<<", y:"<<y<<endl; 
}
58
Bat0u89

最も明確な答え。 「X&const x」は意味をなしますか?

いいえ、ナンセンスです

上記の宣言の意味を理解するには、右から左に読んでください:「xはXへのconst参照です」。しかし、それは冗長です。参照は常にconstであり、別のオブジェクトを参照するように参照を再配置することはできないという意味です。決して。 constの有無にかかわらず。

つまり、「X&const x」は「X&x」と機能的に同等です。 &の後にconstを追加しても何も得られないので、追加するべきではありません。これは人々を混乱させます。

79
Bat0u89

ステートメントicr=y;は、参照がyを参照しないようにします。 yの値を、icrが参照する変数、iに割り当てます。

参照は本質的にconstです。つまり、参照するものを変更することはできません。本当に「constへの参照」である「const参照」があります。つまり、参照するオブジェクトの値を変更することはできません。それらはconst int& または int const& のではなく int& constしかし。

49
mattnewport

定数参照(定数への参照ではない)とは
A 定数参照は、実際には定数への参照です。

定数参照/定数への参照は、次のように示されます。

int const &i = j; //or Alternatively
const int &i = j;
i = 1;            //Compilation Error

基本的には、参照が参照する型オブジェクトの値を変更することはできません。
例:
const参照を介して変数jの値(assign 1)を変更しようとすると、iはエラーになります。

読み取り専用参照「i」の割り当て


icr=y;          // Can change the object it is pointing to so it's not like a const pointer...
icr=99;

参照を変更しません。それはassigns参照が参照する型の値です。初期化時にバインドされている変数以外の変数を参照する参照はできません。

最初のステートメントassigns the y to i
2番目のステートメントassigns the 99 to i

25
Alok Save

このコードは不正な形式です:

int&const icr=i;

リファレンス:C++ 17 [dcl.ref]/1:

typedef-nameまたはdecltype-specifierを使用してcv-qualifierが導入された場合を除き、cv-qualified参照は不正な形式です。この場合、cv-qualifiers無視されます。

このルールは、C++のすべての標準バージョンに存在します。コードが不正な形式であるため:

  • 使用しないでください。
  • 関連する動作はありません。

コンパイラはプログラムを拒否する必要があります。そうでない場合、実行可能ファイルの動作は完全に未定義です。

NB:他の回答のどれもまだこれについて言及していないのかわかりません...誰もコンパイラにアクセスできませんか?

3
M.M

「定数参照」とは、あなたが本当に「定数データへの参照」を意味していると推測しています。一方、ポインターは、定数ポインター(ポインター自体が指すデータではなく、定数です)、定数データへのポインター、またはその両方にすることができます。

3
Poodlehat

別の回答で述べたように、参照は本質的にconstです。

int &ref = obj;

オブジェクトで参照を初期化すると、この参照が参照するオブジェクトでこの参照をアンバインドすることはできません。参照はエイリアスのように機能します。

const参照を宣言するとき、それはconstオブジェクトを参照する参照に他なりません。

const int &ref = obj;

constintのような上記の宣言文は、参照によって参照されるオブジェクトの利用可能な機能を決定しています。より明確にするために、pointer参照に相当するconstを示したいと思います。

const int *const ptr = &obj;

したがって、上記のコード行は、const参照と同じように機能します。 追加、最後に言及したい点があります。

参照はオブジェクトでのみ初期化する必要があります

そのため、これを行うとエラーが発生します。

int  &r = 0; // Error: a nonconst reference cannot be initialized to a literal

このルールには1つの例外があります。参照がconstとして宣言されている場合は、リテラルで初期化することもできます。

const int  &r = 0; // a valid approach
2
Ozan Yurtsever