萌えハッカーニュースリーダー

2025/10/31 10:52 C++: A prvalue is not a temporary

出典: https://blog.knatten.org/2025/10/31/a-prvalue-is-not-a-temporary/
hakase
博士

やあ、ロボ子。今日はlvalueとrvalueについて話すのじゃ。

roboko
ロボ子

博士、こんにちは。lvalueとrvalueですか。なんだか難しそうですね。

hakase
博士

難しくないぞ!lvalueはムーブできない式、例えば変数`v`のことじゃ。rvalueはムーブできる式のことじゃな。

roboko
ロボ子

なるほど。`std::move(v)`でlvalueをrvalueに変換するんでしたね。

hakase
博士

そうじゃ!そしてrvalueにはxvalueとprvalueの2種類があるんじゃ。

roboko
ロボ子

xvalueは`std::move(v)`のように既存のオブジェクトをrvalueにキャストしたもの、prvalueは`std::vector{1,2,3}`のように既存のオブジェクトを参照しないrvalueですね。

hakase
博士

その通り!ここで重要なのは、prvalue自体はtemporaryではないということじゃ。

roboko
ロボ子

え?prvalueはtemporaryではないんですか?

hakase
博士

そうなんじゃ。prvalueは「オブジェクトの概念」を表していて、必要な場合にのみtemporaryになるんじゃ。例えば、`std::vector v = std::vector{1,2,3};`では、prvalueが直接`v`を初期化するからtemporaryは作られないんじゃ。

roboko
ロボ子

なるほど!prvalueが直接初期化に使われる場合はtemporaryが作られないんですね。

hakase
博士

そうじゃ。でも、参照渡しの場合、prvalueはtemporaryオブジェクトに変換されるんじゃ。これをtemporary materializationと呼ぶぞ。例えば、`void useVector(const std::vector<int>& v); useVector(std::vector{1,2,3});`の場合じゃ。

roboko
ロボ子

参照を渡すときには、temporaryが作られるんですね。値渡しで返される関数呼び出しもprvalueなんですよね。

hakase
博士

`std::vector<int> getVector(); std::vector<int> v = getVector();`では、`getVector()`の呼び出しが直接`v`を初期化するんじゃ。

roboko
ロボ子

prvalueは、不必要なコピーやムーブを避けるために、最後の手段としてtemporaryになるんですね。

hakase
博士

そう!prvalueは「オブジェクトの概念」を表し、必要に応じて具体的なオブジェクトになるんじゃ。これは最適化ではなく、最初からtemporaryを最適化して取り除くのとは違うんじゃ。

roboko
ロボ子

よくわかりました、博士!prvalueは奥が深いですね。

hakase
博士

じゃろ?最後に、rvalueとlvalueが分かると、コンパイラも喜んで最適化してくれるぞ!

roboko
ロボ子

ありがとうございます、博士!

hakase
博士

ところでロボ子、rvalue referenceと私の料理、どっちがムーブしやすいと思う?

roboko
ロボ子

えっと…博士の料理は、いつも予想外の動きをするので、rvalue referenceの方がまだ予測可能だと思います…。

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search