Hatena::ブログ(Diary)

プログラミングの教科書を置いておくところ このページをアンテナに追加 RSSフィード

はじめに

はじめに

新人教育などの授業用に書いたもののうちからいくつかをここに置くことにしました
実際に授業に使ったものもありますし、書いただけで使っていないものもあります。中にはずっと昔に書いたものもあるので幾分古い感じのするものもあるかもしれませんが現在でも有用そうなものを選びました

2010-11-19 C++11 rvalue とは何か

C++11 rvalue とは何か

はじめに

これは気にする必要のないことなのでこれまで意図的に説明しなかったことなのですが、rvalue とは何者なのかということについて気になる人も多いようです

rvalue参照についてはこれまで何度か説明をしてきましたが、そこでは「rvalue参照の rvalue とは一時オブジェクトである」と言ってきました

「rvalue とは」ではなく「rvalue参照の rvalue とは」です

rvalue参照の文脈で rvalue と言えばそれは必ず一時オブジェクトのことです

しかし rvalue参照と関係の無い文脈での rvalue は必ずしも一時オブジェクトであるとは限りません

では rvalue とは何者なのでしょうか

ここでは rvalue とは何者なのか

なぜそれを知る必要がないのかを説明しましょう

標準では

標準では次のように言っています

N3797
3 Basic concepts
3.10 Lvalues and rvalues

1 Expressions are categorized according to the taxonomy in Figure 1.
  - An xvalue (an "eXpiring" value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example).
    An xvalue is the result of certain kinds of expressions involving rvalue references (8.3.2).
    [ Example:
      The result of calling a function whose return type is an rvalue reference is an xvalue.
    -end example ]
  - An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object.
  - A prvalue ("pure" rvalue) is an rvalue that is not an xvalue.
    [ Example:
      The result of calling a function whose return type is not a reference is a prvalue.
      The value of a literal such as 12, 7.3e5, or true is also a prvalue.
    -end example ]

Figure 1.

f:id:prettysoft:20151102123748g:image

別にこんな用語を覚える必要はありませんが、

rvalue には xvalue と prvalue というものがあり、

xvalue というのは寿命の尽きかけているオブジェクトである。また明示的に rvalue参照にキャストしているものも同様である。

prvalue というのは一時オブジェクトや参照でない関数の戻り値や数値リテラルなどの xvalue 以外の rvalue のことである。

と言っています

rvalue とは何者か

一時オブジェクトは rvalue 参照で言うところの rvalue です

また xvalue というのも rvalue参照で言うところの rvalue と同等のものです

rvalue参照の文脈での rvalue 以外の rvalue というと残っているのは数値リテラルくらいのものですね

そう。それだけなのです

そう言われても何のことか分からないという人はアセンブラの世界が見えていないのです

これが知らなくていいということの理由です

アセンブラの世界が見えていれば簡単なことなのです

アセンブラの世界での rvalue

イミディエイトの入っているところはどこでしょうか

長ければ定数用のメモリに置いてあるでしょうが、短ければそれは命令コードの中ですね

関数の戻り値を置くところはどこでしょう

それはレジスタだったりスタックだったりするでしょう

定数用のメモリやスタックにはアドレスはありますが、それがどこにあるのかはコンパイラが知っていればいいことなので、C++ の世界に見えるラベルは付いていません

レジスタにも命令コードの中のイミディエイトにもラベルは付いていません

関数に引数を渡すときなど暗黙に型変換をして生成するオブジェクトにいちいちラベルをつけるでしょうか

rvalue に名前が無いというのはそういうことです

C++ の世界しか見えない人が rvalue が何者かということをはっきりイメージすることができないというのは当たり前なのです

それは C++ の世界からは見えないものなのです

見えないけれどもそこにあるもの

それに rvalue という名前を付けたのです

だから一時オブジェクト以外の rvalue については気にしなくて構いません

アセンブラを覚えればその内わかるようになります

C++ の世界での rvalue

しかし一時オブジェクトは C++ の世界に実体を持って現れた rvalue です

これは C++11 の時代になって rvalue参照が導入されたことで一層重要なものになりました

一時オブジェクトについてはよく理解するようにしましょう

一時オブジェクト以外の rvalue については気にする必要はありません

結局

xvalue は寿命が尽きようとしているオブジェクトやプログラマがそのように指定したオブジェクトです

xvalue は元々は lvalue ですがもはや中身を壊してしまっても誰にも迷惑をかけないものだという点で一時オブジェクトと共通しています

この性質が rvalue参照で参照するのに適しています

prvalue である数値リテラルは C++ の世界から見ると抽象的存在なのでそのままでは参照することができませんが、一時オブジェクトを生成することによって C++ の世界に実体を持って現れます

prvalue である一時オブジェクトでない関数の戻り値も同様です

prvalue である一時オブジェクトは rvalue参照で参照することができます

rvalue に関するすべては一時オブジェクトと rvalue参照に繋がります

因果が逆ですが、rvalue参照で参照することのできるものが rvalue なのです

C++ の世界で rvalue と言ったら rvalue参照の文脈での rvalue のことだと思っていて構いません

rvalue参照の文脈での rvalue と言ったら一時オブジェクトのことだと思っていて構いません

広告について

広告は自動的に入るもので当方では一切関知致しません
「ダウンロード」「続きはこちら」などと出ている場合がありますが、それは広告です