2012-05-29 15 views
9

私はこのコードは&をコンパイルしたコードスニペットconst参照にintを割り当てることができますか?

const int& reference_to_const_int = 20; 
cout<<"\n reference_to_const_int = "<<reference_to_const_int<<endl;  

に出くわしたが、出力を実行: -

reference_to_const_int = 20 

これは私のためにある不思議なものです。私は参照がメモリを占有しないことを知っているので、&は他の変数へのエイリアスです。したがって、我々は

int& reference_to_int = 30; 

上記の文が与えるエラーをコンパイルしてはならないと言うことはできません: - まさに「のconst int型&」の場合には何が起こっている

error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’ 

?完全な説明が望まれる。

助けてください。

おかげ

+2

これを読む:http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –

+0

はそれをもう少し考えを与えて、それを*合法である*ように見える。そうでない場合は、変数を増やすことなく設定することはできません。 –

+0

@GigaWatt:あなたが話している "それ"は何ですか?私を信じて、 "それ" *合法でなければならない*それは*ある*。 :) –

答えて

11

一時的に作成され、それがconstそれへの参照が、非const 1にバインドすることは違法に拘束する法的ですされています。

それだけのようだ:

const int& reference_to_const_int = int(20); //LEGAL 
     int& reference_to_const_int = int(20); //ILLEGAL 

const参照は、この作品理由です、一時的の寿命を延ばすことができます。それは言語の単なるルールです。

+0

は、代入文の後に一時的に範囲外になることはないので、print文は範囲外になった 'int'を参照しますか? –

+3

@FlorianSowadeいいえ、const参照は一時的なものの寿命を延ばします。 –

+4

しかし、const参照はすべてのケースで寿命を延長しません。また、Microsoft C++コンパイラはルールを破って一時的ではない「コンス」参照をバインドできることにも注意してください。 –

5

この動作は、一時オブジェクトへの参照をバインドするときに何が起こるかを見ると理解しやすくなります。我々は

const int& reference_to_const_int = 20; //A temporay object int(20) is created. 

を記述する場合、コンパイラはこのようなものの中に上記のコード変換:

int temp = 20; 
const int& reference_to_const_int = temp; 

reference_to_const_intがconstのでなかったなら、私たちはreference_to_const_intする新しい値を割り当てることができます。そうすることで、リテラル20は変更されませんが、一時的なオブジェクトでありアクセスできないtempを変更することになります。 const参照のみが一時参照を必要とする値にバインドできるようにすると、const参照が読み取り専用であるため、問題が完全に回避されます。

なぜC++でconst参照が一時オブジェクトやRVALUES(リテラルなど)を受け入れることができますか?

参考になる最も一般的な場所は、関数の引数または戻り値です。 関数の引数として参照が使用されている場合、関数内の参照を変更すると、関数外の引数が変更されます。

機能の場合は、const参照関数は、すべての状況で使用できるようになります引数を作り、/入力として一時オブジェクトまたはリテラルを受け入れ、オブジェクトの機能の点のconstのらし場合は期待することができます。

一時オブジェクトは常にconstです。したがって、const参照を使用しない場合、その引数はコンパイラによって受け入れられません。

void f(int&) {} 
void g(const int&) {} 
int main() 
{ 
    //f(1); //Error 
    g(1); //OK 
} 
関連する問題