STL はプログラマーが auto_ptr をコンテナーに入れることを禁止できることを知りました。たとえば、次のコードはコンパイルされません。
auto_ptr<int> a(new int(10));
vector<auto_ptr<int> > v;
v.push_back(a);
auto_ptr にはコピー コンストラクターがありますが、なぜこのコードはコンパイルできるのでしょうか?
namespace std {
template <class Y> struct auto_ptr_ref {};
template <class X>
class auto_ptr {
public:
typedef X element_type;
// 20.4.5.1 construct/copy/destroy:
explicit auto_ptr(X* p =0) throw();
auto_ptr(auto_ptr&) throw();
template <class Y> auto_ptr(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr&) throw();
template <class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr_ref<X>) throw();
~auto_ptr() throw();
// 20.4.5.2 members:
X& operator*() const throw();
X* operator->() const throw();
X* get() const throw();
X* release() throw();
void reset(X* p =0) throw();
// 20.4.5.3 conversions:
auto_ptr(auto_ptr_ref<X>) throw();
template <class Y> operator auto_ptr_ref<Y>() throw();
template <class Y> operator auto_ptr<Y>() throw();
};
}
copy-constructor がありますが、 non-const
への参照を取ります。一時変数はこれにバインドしない可能性があるため、一時変数が使用されている場所のコンテナ内で型が機能することは事実上禁止されています。さらに、push_back
への参照を受け入れるconst
ため、正確性のために、新しい内部要素をの引数const
からコピー構築することはできません。push_back
(そのウィキペディアのページには、「そのコピー セマンティクスのため、操作で要素のコピーを実行する可能性のある STL コンテナーでは auto_ptr を使用できない可能性がある」と記載されています。これは、コンテナーがコピー コンストラクター内のコードを魔法のように調べて、型を要素型として機能させたい. 代わりに、それは関数のシグネチャに関するものです.)
とにかく、std::auto_ptr
一部の意見でstd::auto_ptr
はばかげているため、C++ 11 の時点で非推奨です。申し訳ありませんstd::auto_ptr
。
コンパイラがその状況をどのように検出するか (または STL がそこでエラーを引き起こす方法) の特定の問題については、コンパイラの正確な出力を読む必要があります。変換の実行に失敗する原因となる一連のエラーが含まれます。 from const X
toX
は const 修飾子を破棄するため、直接または内部の詳細型のX
いずれかになります。std::auto_ptr<>
特に、std::vector::push_back
は引数 by を取り、const &
内部的に、利用可能なコピー コンストラクターを使用して動的配列内の要素をコピーして構築しようとします。この場合std::auto_ptr
、非 const 参照が必要です。次の行の何か:
void push_back( std::auto_ptr<int> const & x ) {
// ensure enough capacity if needed...
new (buffer + size()) std::auto_ptr<int>( x ); // !!! cannot bind x to non-const&
// complete the operation (adjust end pointer, and such)
}
std::auto_ptr は stl コンテナーと互換性がないためです。
std::auto_ptr は単一所有権のコピー セマンティックを使用しており、stl コンテナーはオブジェクトをコピーして構築する必要があります (一部のアルゴリズムではそれを割り当てる必要があります)。
参照カウント スマート ポインター (boost::shared_ptr) を使用する必要があります。
編集
たとえば、これは push_back の署名です
void push_back ( const T& x );
問題は、std::auto_ptr が特殊であり、コピー コンストラクターと割り当て演算子のシグネチャが異なることです。それらは const ではありません。コピーする場合は、auto_ptr を変更します。
auto_ptr& operator= (auto_ptr& a) throw();
auto_ptr (auto_ptr& a) throw();
push_back の要件を満たす auto_ptr を提供することはできません。
他の答えは auto_ptr についてです。
あなたがやろうとしていることを行うには、 std::unique_ptr を使用できる場合はそれを使用します (C++11) 使用できない場合は、shared_ptr を使用できます