技術よりも哲学の問題だと思います:)
根本的な問題は、移動とコピーの違いは何ですか。私は技術的/標準主義的な言語に飛び込むことはしません、それを簡単にやってみましょう:
- コピー:別の同一のオブジェクトを作成します(または、少なくとも、同等に比較する必要があるオブジェクト)
- 移動:オブジェクトを取得して別の場所に配置します
あなたが言ったように、コピーの観点から移動を実装することは可能です:新しい場所にコピーを作成し、元の場所を破棄します。ただし、そこには2つの問題があります。1つはパフォーマンスに関するもので、もう1つはRAIIに使用されるオブジェクトに関するものです。2つのうちどちらが所有権を持つ必要がありますか?
適切なMoveコンストラクターは、次の2つの問題を解決します。
- 元のオブジェクトは破棄されるため、どのオブジェクトが所有権を持っているかは明らかです。新しいオブジェクト
- したがって、ポイントされたリソースをコピーする必要がないため、効率が向上します。
auto_ptr
とはこれunique_ptr
を非常によく表しています。
auto_ptr
あなたはねじれたコピーセマンティクスを持っています:オリジナルとコピーは等しく比較されません。移動セマンティクスに使用できますが、どこかでポイントされたオブジェクトを失うリスクがあります。
一方、それunique_ptr
はまさにそれです。リソースの一意の所有者を保証するため、コピーとそれに続く不可避の削除の問題を回避できます。また、コンパイル時もコピーなしが保証されます。したがって、コピーの初期化を試みない限り、コンテナに適しています。
typedef std::unique_ptr<int> unique_t;
typedef std::vector< unique_t > vector_t;
vector_t vec1; // fine
vector_t vec2(5, unique_t(new Foo)); // Error (Copy)
vector_t vec3(vec1.begin(), vec1.end()); // Error (Copy)
vector_t vec3(make_move_iterator(vec1.begin()), make_move_iterator(vec1.end()));
// Courtesy of sehe
std::sort(vec1.begin(), vec1.end()); // fine, because using Move Assignment Operator
std::copy(vec1.begin(), vec1.end(), std::back_inserter(vec2)); // Error (copy)
したがって、(とは異なり)コンテナで使用できますが、タイプがサポートしていないコピーを伴うため、多くの操作は不可能になります。unique_ptr
auto_ptr
残念ながら、Visual Studioは標準の施行にかなり緩慢である可能性があり、コードの移植性を確保するために無効にする必要がある拡張機能もいくつかあります...標準をチェックするために使用しないでください:)