- 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がなくても大丈夫だって 理解できるだろう。
|