2015-10-12 16 views
6

これは間違いなく、好奇心によって主に引き起こされる厄介な質問です。私たちは次のことを持っていると仮定します。予想通りrvalue参照にリテラル定数を代入するとどうなりますか?

int x = 5; 
int&& xref = std::move(x); 
std::cout << "Before assignment x: " << x << std::endl; 
std::cout << "Before assignment xref: " << xref << std::endl; 
xref = 10; 
std::cout << "After assignment x: " << x << std::endl; 
std::cout << "After assignment xref: " << xref << std::endl; 

出力は次のようになります。

// Before assignment x: 5 
// Before assignment xref: 5 
// After assignment x: 10 
// After assignment xref: 10 

これは理にかなっています。 std::movexをxvalueに変換し、そのメモリロケーションをxrefにバインドし、その内容を変更することができます。

int&& xref = 5; 
std::cout << "Before assignment xref: " << xref << std::endl; 
xref = 10; 
std::cout << "After assignment xref: " << xref << std::endl; 

int x = 5; 
std::cout << "After assignment x: " << x << std::endl; 

出力が直感的である:

// Before assignment xref: 5 
// After assignment xref: 10 
// After assignment x: 5 

この全体的な感覚を作る今、私たちは次のことを持って言うことができます。 5はprvalueなので、定数リテラル5xrefにバインドすることができます。 xrefも変更可能であることが期待されます。また、定数の値が5であることは変更できないと考えています(上記のスニペットの最後の2行には多少の意味があります)。

私の質問は、正確に何が起こっているのですか?定数リテラル5の値を変更しないで、割り当てによって10に変更されたことを知るには、xrefの十分なIDを保持していることをC++はどのように知っていますか?定数のリテラルにバインドされたときに新しい変数がxrefに代入されると作成されますか? constの参照のみがrvaluesに束縛される可能性があるので、この質問は決してC++ 03では出てこなかった。

答えて

4

リテラルの値から初期化され、参照として長く続く一時的なものです。あなたはこのオブジェクトで好きなことをすることができます。

生涯の点では、これはconst int& x = 5と書かれた場合とまったく同じです。ただ、そこには、constが突然変異でそれを証明するのを妨げるため、自動的に作成された一時的なオブジェクトで作業しているという事実はマスクされています。

[C++14: 8.5.3/5]:[..]初期化子式から(8.5)、非クラス型であるタイプの一時的な「CV1T1」が作成され、コピー初期化T1の場合は。次に、参照は一時的なものにバインドされます。 [..]

+1

ありがとうございました。これは私の質問と私が持っていただろうすべてのフォローアップの質問に答える。 – Klam

+0

@Klam:Lightness Industriesのサービスのすべての部分。 –

5
int&& xref = 5; 

は...その寿命ブロックの端まで延長され、5で初期化され、一時的に作成されます。

割り当て

xref = 10; 

はまだ生きている、一時の値を変更します。