2017-07-26 13 views
1

を追加しない何..私は特に二つの違いを理解しようとしてきたXvalues:IDプロパティが、それはすべてのこれらの詳細は、しっかりと相互接続されているだけのことだ、私は質問の広ごめんなさい

値のカテゴリ - xvaluesとprvalues、しかし私はまだ混乱しています。

(prvalueからはxValue違う)アイデンティティSO上で、次の質問で説明されたのプロパティ:定義のためのすべての

Is it correct to say that xvalues have identity and are movable?

まず、受け入れ答えは、引用§5/ 7 xvalueの; cppreference(と私が知っているようにコンパイラによると)では、最初の式はgeneric rvalueである可能性がありますが、必ずしもそうではありません。 xvalue。 ここでどのソースが正しいのですか?

とにかく、私が「アイデンティティ」の概念のために自分自身で開発しようとした精神モデルは、それを持つ表現が実際のプログラムのデータメモリに存在することが保証されるべきであるということです。

このように、文字列リテラルは左辺値であり、プログラム実行全体でメモリに常駐することが保証されますが、数値リテラルはprvaluesです。仮想的に真っ直ぐなasmに格納される。

同じことがfun(1)を呼び出すときに、我々は呼び出し先のフレームにのみパラメータ左辺値になるだろう、すなわち、prvalueリテラルからstd::moveに適用するようだが、fun(std::move(1))を呼び出すときglvalueのはxValue「種類」は、呼び出し元のフレーム内に保持されなければなりません。

しかし、このメンタルモデルは少なくとも私が理解するように、常に実際のメモリに作成されるべき一時的なオブジェクトでは機能しません(例えば、rvalue-ref-taking funcがprvalue引数を持つfun(MyClass()) )。だから私はこの精神モデルが間違っていると思います。

xvaluesの 'identity'プロパティについて考える正しい方法は何でしょうか?私はアイデンティティでそれを読んだが、私はアドレスを比較することができますが、2 MyClass().member(xvalueはcppreferenceに従って)のアドレスを比較できる場合は、rvalue refをいくつかの比較関数に渡すと、なぜ私は理解できないのですか? 2 MyClass()(prvalue)と同じことをすることはできませんか? std ::動き(a)は右辺値であっても、その評価は一時的なオブジェクトを作成できません What are move semantics?

注:これに接続して

つ以上のソースはこちらの答えです。この難題は、委員会に第3の価値カテゴリーを導入させた。 rvalue参照にバインドできるものは、従来の意味でのrvalueではないものの、xvalue(eXpiring値)と呼ばれます。

これは「アドレスを比較できる」とは関係がないように思われますが、これはrvalueの '従来の意味'とはどのように違うのか分かりません。 b)なぜそのような理由が言語の新しい価値カテゴリを必要とするのか理解できません(これは、OOの意味でオブジェクトの動的な型定義を提供できますが、xvaluesはオブジェクトを参照するだけではありません)。

+2

新しい規則(C++ 17)では、prvaluesが再定義され、prvalue-xvalue変換「一時的なマテリアライゼーション」が導入されています。 2つのMyClass()prvaluesを比較関数に渡そうとすると、参照初期化の一部としてこの変換が行われます。 – Cubbi

+0

@Cubbi hm、あなたはC++ 17がこの「メモリに格納されていることが保証された」コンセプトと一貫性を持たせることを意味しますか?私は思いつきましたか、または実現化の根拠は純粋にelutionでしたか?私はコンセプトがスタンダードの言葉のどこにもないことを理解していますが、外部の観点からは、物事がどのように定義されているかを実際に遵守しているようです。 – ledonter

+0

それはより一貫しているようです、はい。 C++ 14 rvalue refは、クラスprvalueとクラスxvalue初期化子の両方に "直接"バインドします。 ([dcl.init.ref] /5.2)。今ではxvaluesに直接バインドされますが、prvaluesと結果のxvaluesにバインドされます。 – Cubbi

答えて

3

私は個人的に身元と記憶とその他のものを直接扱わない別のメンタルモデルを持っています。

ピュア右辺値「純粋で一時的なものであるオブジェクトを参照:xvalueは「期限切れ値」から来ていると私は私の精神的なモデルで使用し、この情報がある一方で

prvalue

は「純粋な右辺値」から来ていますセンス(sense) ":コンパイラが評価が、作成されたばかりですぐに終了するオブジェクトであることを絶対確実に伝えるための式です(参照バインディングで寿命を延ばすために介入しない限り)。オブジェクトは、表現の評価中に作成され、 "母の表現"の規則に従って死ぬでしょう。これとは対照的に

期限切れ値がまもなく期限切れにを約束しているオブジェクトへの参照に評価される式です。それは、あなたがこのオブジェクトにしたいことを何でもすることができるという約束をあなたに与えるのです。なぜなら、それはとにかく次に破壊されるからです。しかし、このオブジェクトがいつ作成されたのか、それが破壊されるはずなのかはわかりません。あなたはちょうど死ぬように、あなたがそれを「傍受した」ことを知っています。実際に

:この例では

struct X; 
auto foo() -> X; 
X x = foo(); 
     ^~~~~ 

foo()prvalueになります評価します。この式を見るだけで、このオブジェクトはfooの戻り値の一部として作成され、この完全な式の最後に破棄されることがわかります。

const X& rx = foo(); 

今のfooによって返されるオブジェクトは、それが一生この例ではrx

auto bar() -> X&& 
X x = bar(); 
     ^~~~ 

の寿命にprolonguedいました:あなたはこれらの事のすべてを知っているので、あなたはそれが寿命だプロローグすることができますbar()と評価するとxvalueとなります。 bar約束しますあなたはあなたに期限切れになるオブジェクトを与えていますが、このオブジェクトがいつ作成されたかはわかりません。それはbar(一時的なものとして)の呼び出しの前に道を作成することができますし、barあなたにrvalue referenceを与える。利点は、それが後で使用されないため(たとえば、そこから移動できるため)、あなたが望むものを何でもできます。しかし、あなたはこのオブジェクトがいつ破壊されるはずかわかりません。そのようにあなたはそれが寿命だ拡張することはできません - あなたは、元の存続期間は、最初の場所にあるかわからないので:

const X& rx = bar(); 

これは、寿命を延ばすことはありません。

0

func(T&& t)を呼び出す場合、発信者は「ここにはあります」と言っていますが、「自分が何をするのか気にしません」と言っています。C++は "ここ"の性質を指定していません。

参照パラメータがアドレスとして実装されているプラ​​ットフォームでは、オブジェクトがどこかに存在する必要があります。そのプラットフォームでは、アイデンティティ==アドレス。しかし、これは言語の要件ではなく、プラットフォーム呼び出し規約の要件です。

プラットフォームは、呼び出し元と呼び出し先の両方で特定の方法で登録されるオブジェクトを配置するだけで参照を実装できます。ここで、アイデンティティは「登録する」ことができます。

関連する問題

 関連する問題