Garbage Collection

塵も積もれば山

目次

Blog 利用状況

ニュース

C++とかC#とか数学ネタを投下していく予定です。

[その他のページ]
日々の四方山話を綴った日記出水の日記帳

書庫

日記カテゴリ

[C++]右辺値参照の限界点

右辺値参照を調べてわかった事。

右辺値参照はオブジェクトのコピーをするときに
条件さえ整えば高速におこなう事を目的に作られた構文です。

右辺値参照が役に立つのは、関数内でポインタの形で情報を持っているものに限られます。
ですから、直接値を持つ形になっているクラスには何の貢献もしません。
具体的には、以下のような例です。

/* 役に立つ例 */
class MyString{
  char *string;
} 

/* 役に立たない例 */
class Matrix44{
  float m[4][4];
} 

下の例の行列なんかは演算子オーバーロードで書ければすっきりするのですが、
実際にはそういうわけにはいきません。

/* こんな関数は速くならない */
Matrix44 operator +(const Matrix44 &in1, const Matrix44 &in2); 

/* 現実的な解 */
void Add(Matrix &out, const Matrix44 &in1, const Matrix44 &in2); 

右辺値参照を最初に聞いた時、こんな事ができる!と期待してました。

/* 私がやりたかった事 */
auto operator +(const Matrix44 &in1, const Matrix44 &in2) -> Matrix44 &out{
  for(int x = 0; x < 4; x++){
    for(int y = 0; y < 4; y++){
      out[x][y] = in1[x][y] + in2[x][y];
    }
  }
}

返り値を受け取る変数って、関数を呼び出した時点で
破壊されているものとみなしてもいいと思うんですよ。(例外やlongjmpは無視)
そして、その返り値を受け取る変数の参照が欲しい!!

ということで名前付き返り値なんてものがあってもいいんじゃないかな~。
VBなんかが返り値は関数名と同名の変数に入れるタイプですね。

と思ってたら、どうやらReleaseモードでの最適化で似たような事をしてくれるらしいです。
(以下の記事のコメント欄参照)
http://blogs.wankuma.com/episteme/archive/2010/08/06/192085.aspx

…最適化してくれるのなら右辺値参照はいらない子なんじゃと思う今日この頃です。
コピー以外に使い道はあるんでしょうかね?

投稿日時 : 2010年8月21日 11:14

Feedback

# re: [C++]右辺値参照の限界点 2010/08/21 12:29 憂煉

Matrix44 operator +(const Matrix44 &in1, const Matrix44 &in2);
これだとm1 + m2 = m3みたいな意味不明な式が書けてしまうので、
const Matrix44& operator +(const Matrix44 &in1, const Matrix44 &in2);
とするのが好きだったりします。

# re: [C++]右辺値参照の限界点 2010/08/21 21:38 出水

>Matrix44 operator +(const Matrix44 &in1, const Matrix44 &in2);
>これだとm1 + m2 = m3みたいな意味不明な式が書けてしまうので、
関数の返り値は右辺値です
それに代入は出来ないはずです

>const Matrix44& operator +(const Matrix44 &in1, const Matrix44 &in2);
あと、これはまずい構文じゃないですか?
返り値が参照型になっているってことは、どこに実体があるんでしょう?
ローカル変数には出来ないし、staticを付けるとスレッドセーフになりません

# re: [C++]右辺値参照の限界点 2010/08/21 22:07 憂煉

すいません。const Matrix44&を返せるのは演算子が(意味的に)?=の働きの場合のみですね…
ですが、C++03だと普通に上の代入が通ってしまうんですよ。
C++0xはやく普及しないかなー

# re: [C++]右辺値参照の限界点 2010/08/21 23:29 アキラ

> staticを付けるとスレッドセーフになりません

http://d.hatena.ne.jp/bsdhouse/20100128/1264693781

# re: [C++]右辺値参照の限界点 2010/08/21 23:57 憂煉

あ、普通にconst Matrix44返せばいいか…
それで最適化で上手く繋がってくれれば右辺値要らない筈。
とはいっても関数の戻り値はリンク時の最適化が必要だから、GCCには厳しいよなとか思って調べたら4.5以降でリンク時最適化機能が追加されてますね。

# re: [C++]右辺値参照の限界点 2010/08/22 7:58 出水

>アキラさん
ブロックstaticは局所的グローバル変数じゃなくて
スレッド毎に独立した変数が作られる、ってことです?

今のitoaはスレッドセーフですけど、
昔のitoaは他のスレッドの結果を取り込む危険性がありましたよね?
それが完全になくなった、って考えていいですか?

# re: [C++]右辺値参照の限界点 2010/08/24 12:27 アキラ

static変数の生成がスレッドセーフ、ですね。
スレッドごとに独立した変数がほしければthread_localキーワードで。

itoa・・・文脈がよくわかんないです。

# re: [C++]右辺値参照の限界点 2014/09/25 18:27 ac

遅レスですが、moveは元々STLコンテナのパフォーマンスを上げるために生まれたわけではありません。

moveが無いとスマートポインタを実装できないからです。

タイトル
名前
Url
コメント