2013-06-28 15 views
6

私はhttp://thbecker.net/articles/rvalue_references/section_01.htmlを読んでいる間、私はちょっと切った。右値と左値の正確な差

// lvalues: 
// 
int i = 42; 
i = 43; // ok, i is an lvalue 
int& foo(); 
foo() = 42; // ok, foo() is an lvalue 
int* p1 = &foo(); // ok, foo() is an lvalue 

// rvalues: 
// 
int foobar(); 
int j = 0; 
j = foobar(); // ok, foobar() is an rvalue 
int* p2 = &foobar(); // error, cannot take the address of an rvalue 
j = 42; // ok, 42 is an rvalue 

なぜINT * P2 = & foobarに()。エラー文、int * p1 = & foo();エラーではありません。最初の値は右値ですが、後で左辺値はどのようになりますか?事前

+0

私はあなたの最後の文にそれが後にあると信じます –

答えて

4

おかげだから我々は2つの機能があります。

int& foo(); 
int foobar(); 
  • foo
  • foobarをintに左辺値参照を返す関数はint型
を返す関数であります

関数呼び出し式:

foobar() 
foo() 

の両方が(そうfoo()intなくlvalue-reference to int型を持つ、参照が表現から削除されます)int型を持っています。 2つの式は、異なる値の種類を有する:

  • foobar()はprvalueある(非参照を返す関数への関数呼び出しがprvalueある)
  • foo()を返す関数への左辺値(関数コールであります左辺値参照左辺値である)

あなたは(prvalueが右辺値の一種である)右辺値のアドレスを取ることができないので、&foobar()が許可されていません。

左辺のアドレスを取ると、&foo()が許可されます。

+0

なぜfooのアドレスを取ることができないのですか? –

+0

@ ss7don:あなたは式 'foo()'を意味しますか? 'foo()'のアドレスを取ることができます。私の答えの最後の行をもう一度読んでください。 –

+0

私はそれが妥当と思われるので、答えを受け入れました。率直に言って、私はまだfooとfoobarの正確な違いを理解していません。どちらも関数です。しかし、どれが右値で、もう一つが左値であるか。 –

6

下記の例のコードがCにあるとします。コンパイルできますか?この問題では、左辺値と右辺値の概念はどのように機能しますか?

#define X 8 
int main(void) 
{ 
    ++X; // will this line compile? 
     return 0; 

} 

上記のコードと問題が本当に理解できるように、左辺値と右辺値の概念を少し説明する必要があります。先に進む前に、ここで提示されている左辺値と右辺値の定義は正確ではないことに注意してください。

右辺値と左辺値

オブジェクトとの間の差を調べ、必ずしも修正されないことができるメモリの領域です。左辺値は、そのようなオブジェクトを参照する式です。 lvalueという用語は、もともと表現の左側(したがって 'l')に現れるオブジェクトを参照していました。 const修飾された型もlvalueと見なされるので、その定義はもはや適用されませんが、変更できないため代入文の左側に決して現れません。したがって、 "変更可能な左辺値"という用語は、変更可能な左辺値を参照するために作成され、const修飾された型はこのカテゴリに該当しません。

rvalueは値を持ちますが、値を割り当てることのできない式です。右辺値は左辺値ではない式であるとも言えます。右辺値の例は、 '8'や '3.14'のようなリテラル定数です。したがって、明らかに上記のコードの値 '8'はrvalueです。質問

に答えるために、左辺値と右辺値の我々の理解を使用して

は、今度は、問題を解決するために試してみましょう。厳密に言えば、接頭辞(または接尾辞)インクリメント演算子のオペランドは変更可能な左辺値でなければなりません。だから、上のコードで接頭辞インクリメント演算子のオペランドは何ですか?

Xはマクロなので、プリプロセッサの実行後、上記の文は "++ 8"に展開されます。これは接頭辞インクリメント演算子のオペランドが "8"であることを意味します。そして、8はrvalueなので、 "++"の引数として使うことはできません。これは、上記のコードがコンパイルされないことを意味します。

+1

とてもいいですが、この例を気にするのはなぜですか?どのようにクイズの質問の種類がこの問題の理解に役立つことがわかりません。 – SChepurin

関連する問題