Humanity

Edit the world by your favorite way

rvalue reference - 続き

珍しく続いた!ということでhitoさんのこのエントリ読んだまとめとか。感想とか。

  • std::moveというテンプレート関数の実態はただのキャスト。実際に「Moveする」のはMoveコンストラクタ
  • テンプレート関数の引数の型がrvalue referenceであった場合、その変数の型はlvalue referenceである可能性もある *1
  • std::forwardはそういったrvalueかlvalueか曖昧な場合のための関数
    • rvalueの場合はrvalueにキャストし、lvalueの場合はlvalueにキャストする
  • rvalue用の関数の他にlvalue用の関数がオーバーロードされていればrvalueのは必ずrvalueであるのでstd::moveを使って構わない。ただlvalue用の関数を削除した場合などに備えてstd::forwardを使うべきだと思う
  • std::moveは型がlvalueであってもrvalueであってもrvalueを返すキャスト。std::forwardはrvalueの場合はrvalueを返し、lvalueの場合はlvalueを返すキャスト。
  • そんなわけでstd::moveに渡された変数はその後のコードで使ってはいけない。Moveされているかもしれないので。
  • const参照とrvalueとの違いはなんだろう?const参照って別にconstなわけじゃなくてrvalueも受け取れるってだけだよね?
    • でもやっぱりMove Semanticsは新しい概念なので新しい構文を用意した方が分かりやすいか

あと「賢いコンパイラの場合」の章を見て思わず苦笑いした。
最適化にまつわる色々はなかなか面倒だなぁ。
でもそれでコピーされずに*2済むのはいいことなのかな。多分。

*1:テンプレートでない関数の引数の場合はどうなんだろう

*2:Moveコンストラクタさえも呼ばれずに