6

STL はプログラマーが auto_ptr をコンテナーに入れることを禁止できることを知りました。たとえば、次のコードはコンパイルされません。

    auto_ptr<int> a(new int(10));
    vector<auto_ptr<int> > v;
    v.push_back(a);

auto_ptr にはコピー コンストラクターがありますが、なぜこのコードはコンパイルできるのでしょうか?

4

4 に答える 4

11

の定義をstd::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

于 2011-09-09T09:10:49.843 に答える
6

コンパイラがその状況をどのように検出するか (または STL がそこでエラーを引き起こす方法) の特定の問題については、コンパイラの正確な出力を読む必要があります。変換の実行に失敗する原因となる一連のエラーが含まれます。 from const XtoXは 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)
}
于 2011-09-09T09:20:52.040 に答える
0

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 を提供することはできません。

于 2011-09-09T08:59:48.697 に答える
0

他の答えは auto_ptr についてです。

あなたがやろうとしていることを行うには、 std::unique_ptr を使用できる場合はそれを使用します (C++11) 使用できない場合は、shared_ptr を使用できます

于 2011-09-09T09:04:11.370 に答える