EDIT: I should've mentioned, I was looking at the documentation for Boost's ptr_sequence_adapter
and it claims that their adapter for template< class U > void push_back( ::std::auto_ptr<U> x );
is equivalent to doing vec.push_back(autoPtr.release());
and also provides the strong exception guarantee. And then I realized I was confusing their description of the effect of the implementation for what the implementation actually was, and so this question is semi-nonsensical. I'm just leaving it here for posterity.
To me, it seems the call to std::auto_ptr<t>
would succeed, and then the call to std::vector<t*>::push_back
could throw an exception, and the pointer would be leaked.
It seems like you'd have to do this instead:
vec.push_back(0); //Attempts to allocate space in vector, could throw bad_alloc
vec.back() = autoPtr.release(); //Provides nothrow
This is specifically a feature of the Boost pointer containers library.
The base push_back
member function is defined as:
void push_back( value_type x ) // strong
{
this->enforce_null_policy( x, "Null pointer in 'push_back()'" );
auto_type ptr( x ); // notrow
this->base().push_back( x ); // strong, commit
ptr.release(); // nothrow
}
(from the ptr_sequence_adapter.hpp header)
So, the push_back
function itself takes ownership of the pointer and if reallocation fails, it takes responsibility for deleting the pointer.
The push_back
overload that takes an auto_ptr
is defined in terms of the base push_back
function:
template< class U >
void push_back( std::auto_ptr<U> x )
{
push_back( x.release() );
}
The pointer is released before the call to the base push_back
, which is okay because the base push_back
function has a strong guarantee that it will delete the pointer if an exception is thrown.