標準コンテナで std::auto_ptr<> を使用するのが間違っているのはなぜですか?

StackOverflow https://stackoverflow.com/questions/111478

質問

なぜ使い方が間違っているのか std::auto_ptr<> 標準コンテナでは?

役に立ちましたか?

解決

C ++標準によると、STL要素は「コピー構築可能」および「割り当て可能」でなければならないと述べています。言い換えれば、要素を割り当てたりコピーしたりすることができ、2つの要素は論理的に独立しています。 std::auto_ptr はこの要件を満たしていません。

たとえば、次のコードを考えてみましょう。

class X
{
};

std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);

std::auto_ptr<X> pX = vecX[0];  // vecX[0] is assigned NULL.

この制限を克服するには、 std::unique_ptr, std::shared_ptr または std::weak_ptr C++11 をお持ちでない場合は、スマート ポインターまたはブースト同等のものを使用してください。 これらのスマート ポインターのブースト ライブラリのドキュメントは次のとおりです。

他のヒント

コピーセマンティクスauto_ptr コンテナと互換性がありません。

具体的には、コピーする auto_ptr 一方がポインタの所有権を失っているため、他方への実行は 2 つの等しいオブジェクトを作成しません。

より具体的に言うと、 auto_ptr これにより、コピーの 1 つがポインタを放します。これらのうちどれがコンテナ内に残るかは定義されていません。したがって、保存するとポインターへのアクセスがランダムに失われる可能性があります。 auto_ptrs コンテナの中。

このテーマに関する 2 つの非常に優れた記事:

STL コンテナーは、そこに保存されているアイテムをコピーできる必要があり、オリジナルとコピーが同等であることを期待するように設計されています。自動ポインタ オブジェクトにはまったく異なる契約があり、コピーすると所有権が移転されます。これは、auto_ptr のコンテナーが使用状況に応じて奇妙な動作を示すことを意味します。

何が問題になるかについては、Effective STL (Scott Meyers) の項目 8 に詳しく説明されています。また、それほど詳しくない説明は、Effective C++ (Scott Meyers) の項目 13 にあります。

STL コンテナには、含まれるアイテムのコピーが保存されます。auto_ptr がコピーされると、古い ptr が null に設定されます。この動作により、多くのコンテナ メソッドが壊れます。

C++03 標準 (ISO-IEC 14882-2003) 第 20.4.5 項第 3 項で次のように述べています。

[...] [注記:...] auto_ptrは、標準のライブラリコンテナ要素の模倣と割り当て可能な要件を満たしていないため、標準的なライブラリコンテナをAUTO_PTRでインスタンス化すると、未定義の動作が発生します。— エンディングノート]

C++11 標準 (ISO-IEC 14882-2011) 付録 D.10.1 パラグラフ 3 には次のように記載されています。

[...] 注記:...] auto_ptrのインスタンスは、可動構造と動きのある要件を満たしていますが、模倣可能でコピー割り当て可能の要件を満たしていません。— 終了ノート]

C++14 標準 (ISO-IEC 14882-2014) 付録c.4.2附属書Dで述べています:互換性機能:

変化:クラステンプレートAUTO_PTR、unary_function、およびbinary_function、functionテンプレートrandom_shuffle、および関数テンプレート(およびそのリターンタイプ)ptr_fun、mem_fun、mem_fun_ref、bind1st、およびbind2ndは定義されていません。
理論的根拠:新しい機能によって置き換えられます。
元の機能への影響:これらのクラステンプレートと関数テンプレートを使用する有効なC ++ 2014コードは、この国際標準でコンパイルできない場合があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top