Search code examples
c++stlauto-ptr

Why vector.push_back(auto_ptr) wouldn't compile?


I learned that STL can forbid programmer putting an auto_ptr into a container. For example following code wouldn't compile:

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

auto_ptr has the copy constructor, why this code can even compile?


Solution

  • Looking at the definition of 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();
        };
    
    }
    

    Although there is a copy-constructor, it takes a reference to non-const. Temporaries may not bind to this, so the type is effectively prohibited from working inside containers in any place where temporaries are used; in addition, push_back accepts a reference to const, so due to const-correctness it's impossible for the new, internal element to by copy-constructed from push_back's argument.

    (That Wikipedia page says that "because of its copy semantics, auto_ptr may not be used in STL containers that may perform element copies in their operations"; this doesn't mean that containers magically examine the code inside the copy constructor to decide whether it wants to make the type work as an element type. Instead, it's just about the function signature.)

    Anyway, std::auto_ptr is deprecated as of C++11 because, in the opinion of some, std::auto_ptr is silly. Sorry, std::auto_ptr.