222

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

4

6 に答える 6

125

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.

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

于 2008-09-21T17:47:35.863 に答える
66

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

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

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

于 2008-09-21T17:29:13.987 に答える
39

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

于 2010-06-25T19:01:08.453 に答える
17

STL コンテナーは、格納するアイテムをコピーできる必要があり、元のコンテナーとコピーが同等であることを期待するように設計されています。自動ポインター オブジェクトには、完全に異なるコントラクトがあり、コピーすると所有権が譲渡されます。これは、auto_ptr のコンテナーが、使用状況によっては奇妙な動作を示すことを意味します。

何がうまくいかないかについては、Effective STL (Scott Meyers) の項目 8 に詳細な説明があり、Effective C++ (Scott Meyers) の項目 13 にはそれほど詳細ではない説明もあります。

于 2008-09-21T17:40:43.680 に答える
12

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

于 2008-09-21T17:44:30.380 に答える
4

C++03 標準 (ISO-IEC 14882-2003)は、条項 20.4.5 パラグラフ 3 で次のように述べています。

[...] [注: [...] auto_ptr は、標準ライブラリ コンテナー要素の CopyConstructible および Assignable 要件を満たしていないため、auto_ptr を使用して標準ライブラリ コンテナーをインスタンス化すると、未定義の動作が発生します。— エンドノート]

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

[...] 注: [...] auto_ptr のインスタンスは、MoveConstructible および MoveAssignable の要件を満たしていますが、CopyConstructible および CopyAssignable の要件を満たしていません。— エンドノート]

C++14 標準 (ISO-IEC 14882-2014)は、付録 C.4.2 付属書 D: 互換機能で次のように述べています。

変更: クラス テンプレート auto_ptr、unary_function、および binary_function、関数テンプレート random_shuffle、および関数テンプレート (およびそれらの戻り値の型) ptr_fun、mem_fun、mem_fun_ref、bind1st、および bind2nd は定義されていません。
理由: 新しい機能に取って代わられました。
元の機能への影響: これらのクラス テンプレートと関数テンプレートを使用する有効な C ++ 2014 コードは、この国際標準でコンパイルできない場合があります。

于 2012-10-30T14:30:30.003 に答える