2016-04-11 7 views
2

私はC++を初めて使っています。これは私の最初の質問ですので、私と一緒にいらしてください...私はしばらくの間、左辺値と右辺値について読んできました。ほとんどのことを理解していると思いますが、rvalue referenceとxvalueの違いは何ですか?

int x = 32; 
int& Lref = x; // Lref is lvalue ... ok 
int& funcA(); // calling funcA() is lvalue ... ok 

int&& Rref = 32; // Rref is lvalue ... ok I got this 
int&& funcB(); // calling funcB() is rvalue ... Why? 

:...ので、私の質問は

右辺値参照は左辺値(私は理解してこの部分)と考えられているが、右辺値参照を返す関数が右辺値(またははxValueは、具体的には)考えられているインスタンスの特定になりますしたがって、問題は、rvalue参照を返すfuncB()を呼び出すことがrvalueとみなされる理由は?

ありがとうございます。

+0

'rvalue references are lvalue'それ以外の場合は2つの異なる型はありません –

+0

' Lref'は左辺の参照ですが、 '32'はそうではなく、実際にはコンパイルされません。同じように 'const&'または '&&'が必要です。 – edmz

+0

@黒はい私は間違いを犯したので、ただ修正した。 – Laith

答えて

3

をお知らせ http://en.cppreference.com/w/cpp/language/value_category

、「右辺値参照が」「はxValue」一方で、タイプの一種であります一種の表現です。

右辺値参照は左辺値(私は理解してこの部分)

彼らではないと考えられています。右辺値参照は型であり、型は式ではないため、左辺値とみなすことはできません。あなたが言及しているのは、式がタイプT&&の変数の名前だけで構成されている場合、タイプTの左辺式です。

なぜ右辺値参照を返した()を呼び出すfuncBのが最も簡単な答えは「定義上」になり右辺値

と考えられています。関数の戻り値の型がT&&の関数呼び出し式は、Tのxvalue式です。モチベーションに関しては、これはまさにstd::moveが何をするのかを示すものです。移動する能力を持つ任意の式をimbueします( "rvalue category"としても知られています - http://en.cppreference.com/w/cpp/language/value_category参照)。

+0

私はそれを認めます左値型、右値型、型控除トピックは非常に混乱しています。さらに、ほとんどのWebサイトでは、それらを明確な方法で説明していません...それらを理解するのを助けた唯一の方法は、Scott Meyers自身のビデオを見て、今私は理解しています...そしてあなたの答えに感謝します – Laith

+0

@WLION彼はこれをより複雑にすると思います。 – Cubbi

1

一般に、関数によって返される「オブジェクト」は、関数自体に関連付けられたスタック部分に作成されます。つまり、返される値は新しいオブジェクトにコピー(または移動)されなければならず、このオブジェクトはrvalueです。

コードでは、lrefの間違いがありました。 32はr値のリファレンスです。

単純にすると、左辺値は、アドレスを取得できるオブジェクトです。右辺値参照のアドレスは取得できません。

int a = 50; 
int &b = a; // Ok because we can get the address of a 
int &c = 50; // Error we can't get the address of 50 
int &&d = 50; // It is ok 

「オブジェクト」と同様に機能します。

たとえば、copyableではないunique_ptrを持つコードを取ります。

std::unique_ptr<int> foo() { 
    auto ptr = std::make_unique<int>(5); 
    return ptr; 
} 
auto a = foo(); // is correct, the ptr will be moved because it is a rvalue 

この関数は正しい値を返す必要があります。 (通常は、左辺値または右辺値に左辺値参照を使用するかどうかを指定しない場合はコンパイラが使用します)。

たぶん、あなたが見てかかることがあります:それは不明である場合は、名ばかりの質問に答えるために、私は

+0

はい、私は間違いを犯しましたが、私はただそれを修正しましたが... "値の参照のアドレスを取得できません" ...私はちょうど&Rrefのアドレスを得て、意味が成立しないようにしました。 – Laith

+0

多分私はうまく説明しませんでした。 変数を参照値として宣言しているため、その変数からアドレスを取得できないためではありません。あなたは "彼女が指している"値のアドレスを取得することはできません –

+0

私はすでに理解している..私はすでに理解している..しかし、私の問題は、これらの違いについてのみ int&& Rref; // Rrefがlvalue ..................... int && Func()// Funcを呼び出すのがrvalue – Laith

関連する問題