2011-12-22 9 views
17

当然のことながら、これはコンパイルされませんリテラル番号は変更可能かどうか?</p> <pre><code>int &z = 3; // error: invalid initialization of non-const reference .... </code></pre> <p>をし、これがコンパイルされます:

const int &z = 3; // OK 

を今、検討してください:

const int y = 3; 
int && yrr = y; // const error (as you would expect) 
int && yrr = move(y); // const error (as you would expect) 

しかしこれらの次の行を私のためにコンパイルします。私はそうすべきではないと思う。

int && w = 3; 
int && yrr = move(3); 
void bar(int && x) {x = 10;} 
bar(3); 

最後の2行でリテラル3を変更できないのでしょうか? 3とconst intの違いは何ですか?最後に、リテラルを「変更する」ことに危険がありますか?

(G ++ - -std=gnu++0x -Wall -Wextra 4.6(GCC)4.6.2)

+1

私の自身の質問に答えるには: 'move(3)'の中で、おそらく3が最初にコピーされて一時的なintがステートメントの終わりに破棄されます。これは説明ですか? –

+0

2番目の文には、const &z = 3;が指定されています。コンパイルされません。 –

+0

ありがとうございます、@CJohnson、私は通常、ここに作業コードをコピー&ペーストします。しかし、私はその1つのライナーで不注意でした! –

答えて

13

リテラル3に右辺値参照:

int && w = 3; 

が実際に式を評価した結果である一時的に結合しています3。これは、いくつかのプラトニックリテラル3.

(参考文献は2011年3月のドラフトからであるすべての次の規格、n3242)

3.10/1 "左辺値と右辺値"

The value of a literal such as 12, 7.3e5, or true is also a prvalue

その後8.5にバインドされていません。

Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression using the rules for a non-reference copy-initialization (8.5). The reference is then bound to the temporary.

と、一例として、あなたに何があるかに非常に近い何かを与える:3「参照」は言う最後のケースにフォールスルーリファレンスがバインドされている方法のための規則を与えます質問:

double&& rrd = 2; // rrd refers to temporary with value 2.0 
+0

ありがとう、しかしそれが本当だったら、それはこの作品ではないはずですか? 'move(3)= 6;'代わりにエラー "* error:左辺値としてxvalue(rvalue reference)を使う*"が出ます。 xvalueとprvaluesとそのすべてを再び読むことが私の時間です:-) –

+3

あなたの答えに感謝して、私は数秒前の私のコメントに答えることができると思います。私は 'move(3)'が評価値であることを見ることができます(明らかに、それは無名です)。私の関数 'void bar(int && x){x = 10;}'の中に 'x'の名前があります。これは 'x = 6'と' move(3)= 6'の違いと思われます。どちらも '&&'ですが、一方は左辺値であり、もう一方は左辺値ではありません。そして、この区別は 'move(3)= 6'のエラーメッセージにつながります。 –

+0

@Aaron:あなたのコメントに(遅く)追加:どこかで、標準は指定されたrvalueが左辺値であることを指定しています。 :) – Xeo

関連する問題

 関連する問題