C ++ 11の「move」(r値参照)で何ができstd::auto_ptr
ますか?(私が理解しているように、それらは1つのアイデアの異なる実装です。)
そして再び古い質問:std::auto_ptr
とても悪いコンポーネントですか?
C ++ 11の「move」(r値参照)で何ができstd::auto_ptr
ますか?(私が理解しているように、それらは1つのアイデアの異なる実装です。)
そして再び古い質問:std::auto_ptr
とても悪いコンポーネントですか?
C++98/03 には、真に「移動可能な」クラスという概念がありません。auto_ptr
transfer-on-copy-semantics を持つクラスです。つまり、コピーを作成すると、元の内容が変更されます (非 const 引数を持つコピー コンストラクタに注意してください!)。これは悪いです。このようなクラスは、標準コンテナでは使用できません。
C++11 では、新たに追加された右辺値参照の概念のおかげで、真に移動可能なクラスの概念が導入されています。unique_ptr
完全に置き換わる新しいは、auto_ptr
まったくコピーできなくなりますが、代わりに移動可能になります。すべての標準コンテナは、可能であればオブジェクトの移動を試行するように更新されたため、移動専用オブジェクトを標準コンテナに格納できるようになりました。移動のみ可能でコピー可能ではないオブジェクトの他の例としては、ミューテックス、ロック、スレッド、および iostream があります。
要点を突き詰めるために、架空の壊れた C++98 コードと、対応する C++11 コードを比較します。
std::auto_ptr<Foo> p1(new Foo);
std::vector< std::auto_ptr<Foo> > v1;
//v1.push_back(p1); // eeww, what is the state of p1 now? ERROR
std::unique_ptr<Foo> p2(new Foo);
std::vector<std::unique_ptr<Foo>> v2;
//v2.push_back(p2); // Error, copying is simply not allowed
v2.push_back(std::move(p2)); // explicit; mustn't read p2 after moving it
v2.emplace_back(new Foo); // even better ;-)
問題std::auto_ptr
は、移動操作のように機能するコピー操作があることです。したがって、コピー操作で動作するアルゴリズムは で動作しauto_ptr
ますが、オブジェクトからのコピーが変更されたため、期待どおりに動作しません。そのauto_ptr
ため、STL コンテナーでは使用できませんが、そうしようとするコードはコンパイルされますが、実行時に機能しません。
std::unique_ptr
一方、コピー操作はありませんが、代わりに移動のみ可能です。したがって、コピーするアルゴリズムstd::unique_ptr
は、操作する必要があるときにコンパイルに失敗しますstd::unique_ptr
。何かが移動操作を使用する場合、移動操作のソースが同じままであるとは想定していないため、混乱はありません。
したがって、基本的には、C++ オブジェクトに対して期待どおりに動作する操作 (またはそうでない) に帰着します。
std::auto_ptr ではできないことを C++11 で 'move' (r-value 参照) で何ができますか?
、などの最も重要な利点はmove
、あなたにはできないが、 ではできることです。unique_ptr
auto_ptr
auto_ptr
このリンクは、非推奨の委員会への理論的根拠を説明していauto_ptr
ます。これには次の結論が含まれています。
結論:
コピー構文を使用して左辺値から移動しないでください。代わりに、移動のための他の構文を使用する必要があります。そうしないと、コピーが意図されたときに汎用コードが移動を開始する可能性があります。
この結論に至った経緯の詳細については、リンクを参照してください。
大きな違いの 1 つは、rvalue 参照 (およびさまざまな移動の最適化) が呼び出し元のコンテキストから自動的に推論/差し引かれることですが、呼び出しサイトで auto_ptr を手動で作成する必要があります。
auto_ptr
は根本的に壊れており、右辺値参照はそうではありません。それはとても簡単です。