トップページ > プログラム > 2014年10月21日 > UehLHyCh

書き込み順位&時間帯一覧

12 位/194 ID中時間01234567891011121314151617181920212223Total
書き込み数0000000000000000000040004



使用した名前一覧書き込んだスレッド一覧
デフォルトの名無しさん
GCは失敗。メモリは自分で管理せよ!

書き込みレス一覧

GCは失敗。メモリは自分で管理せよ!
325 :デフォルトの名無しさん[sage]:2014/10/21(火) 20:32:42.62 ID:UehLHyCh
たったこれだけのことを知っていれば、初心者でも
C++でGCなくても大丈夫だってわかるんだよ。

taro-nishinoの日記: 右辺値参照の簡単入門
http://slashdot.jp/~taro-nishino/journal/506859

右辺値参照の簡単入門
2008年3月10日 Howard E. Hinnant, Bjarne Stroustrup, Bronek Kozicki

要約
右辺値参照はC++言語の小さな拡張である。右辺値参照はプログラマに、論理的に不必要なコピーの回避及び完全転送関数を与える。
それらは、何よりも高パフォーマンスでより強靭なライブラリの設計を支援することを意味する。

始めに
このドキュメントは、新しいC++言語のフィーチャー、右辺値参照の簡単なツアーを与える。完全な論及と言うより、
簡単なチュートリアルである。詳細は、参考文献を見られたい。

右辺値参照
右辺値参照は、C++の従来の参照と非常によく似た合成型である。これらの2つの型をよく区別するために、
C++の従来の参照を左辺値参照と呼ぶ。参照という言葉が使用される時、両方の参照を言及する。つまり、左辺値参照と右辺値参照。

左辺値参照は、ある型の後に&を置くことによって形成される。

A a;
A& a_ref1 = a; // 左辺値参照

右辺値参照は、テンポラリ(右辺値)にバインド出来ることを除いて、左辺値参照と全く同様に振舞う一方で、
(非コンスト)左辺値参照は右辺値にバインド出来ない。

A& a_ref3 = A(); // Error!
A&& a_ref4 = A(); // Ok
GCは失敗。メモリは自分で管理せよ!
326 :デフォルトの名無しさん[sage]:2014/10/21(火) 20:33:18.13 ID:UehLHyCh
質問:一体何故、これをしたいのか?!

右辺値参照と左辺値参照の組合せが、容易にmoveセマンティクスをコードするために必要なことが判明する。
右辺値参照はまた、C++で未だ未解決の問題、完全転送を成就するために使用出来る。
偉くないプログラマの観点から言えば、右辺値参照から得るものは、より一般的で良い実行速度のライブラリである。

Moveセマンティクス
まがい物のコピーを削減する
コピーは高価になり得る。例えば、std::vectorに対してv2=v1は典型的に関数呼出し、
メモリアロケーション、そしてループを伴なう。vectorの2つのコピーを必要とする処では勿論容認出来るが、
多くの場合そうではない。私達はよくvectorを或所から別の場所へとコピーするが、それは古いコピーを上書きするために行う。以下を考えよう。

template <class T> swap(T& a, T& b)
{
T tmp(a); // 今や二つのaコピーを持つ
a = b; // 今や二つのbコピーを持つ
b = tmp; // 今や二つのtmp(aでもある)コピーを持つ
}

しかし、私達はa又はbの何のコピーも欲しくなかったし、それらを交換したかったのだ。やり直し。

template <class T> swap(T& a, T& b)
{
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
GCは失敗。メモリは自分で管理せよ!
327 :デフォルトの名無しさん[sage]:2014/10/21(火) 20:33:54.27 ID:UehLHyCh
このmove()は引数の値をターゲットに与えるが、そのソースの値を保持する必要がない
。そして、vectorに対しては、すべての要素をコピーする必要を避けるように、
move()はその引数をゼロ容量のvectorにすることが当然期待される。言い換えれば、移動(move)は潜在的に破壊的読込みである。

この特別な場合においては、私達は特化によってswapを最適化出来たであろう。
しかし、削除又は更新の直前に、大きなオブジェクトをコピーするすべての関数を特化出来ない。それは手の施しようがないのだ。

右辺値参照の最初の仕事は、冗長性又はランタイムオーバヘッド無しでmove()を実装させることである。

move
move関数は実際は殆ど何もしない。moveがすることは、左辺値又は右辺値の参照を受けて、
コピーコンストラクタを走らせずに右辺値を戻すことだ。

template <class T>
typename remove_reference<T>::type&&
move(T&& a)
{
return a;
}

それらの引数が左辺値か右辺値かどうかについて、主要関数をオーバロードすることはユーザコードの責任である
(例えば、コピーコンストラクタと代入演算子)。引数が左辺値である時、その引数はコピーされなくてはならない。引数が右辺値である時、安全に移動されるであろう。

左辺値/右辺値におけるオーバロード
リソースを所有し、コピーセマンティクス(コピーコンストラクタと代入)を与える簡単なハンドルクラスを考えよう。
例えば、clone_ptrはポインターを所有し、コピー目的のためclone()を呼出してよい。
GCは失敗。メモリは自分で管理せよ!
328 :デフォルトの名無しさん[sage]:2014/10/21(火) 20:34:28.66 ID:UehLHyCh
以下省略。

たったこれだけのことを知っていれば
初心者でもGCがなくても大丈夫だって
理解できるだろう。


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。