Почему `myvector.push_back(autoPtr.release())` обеспечивает строгую гарантию безопасности исключений?
РЕДАКТИРОВАТЬ: я должен был упомянуть, я искал документацию для Boost'sptr_sequence_adapter
и он утверждает, что их адаптер для template< class U > void push_back( ::std::auto_ptr<U> x );
эквивалентно делать vec.push_back(autoPtr.release());
а также предоставляет гарантию сильных исключений. А потом я понял, что путаю их описание влияния реализации на то, что реализация была на самом деле, и поэтому этот вопрос полусмысленный. Я просто оставляю это здесь для потомков.
Мне кажется, это призыв к std::auto_ptr<t>
будет успешным, а затем вызов std::vector<t*>::push_back
может выдать исключение, и указатель будет утечка.
Кажется, что вы должны сделать это вместо этого:
vec.push_back(0); //Attempts to allocate space in vector, could throw bad_alloc
vec.back() = autoPtr.release(); //Provides nothrow
2 ответа
Это особенность библиотеки контейнеров указателей Boost.
База push_back
функция-член определяется как:
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
}
(из заголовка ptr_sequence_adapter.hpp)
Итак push_back
Сама функция принимает владение указателем, и если перераспределение не удается, она берет на себя ответственность за удаление указателя.
push_back
перегрузка, которая принимает auto_ptr
определяется с точки зрения базы push_back
функция:
template< class U >
void push_back( std::auto_ptr<U> x )
{
push_back( x.release() );
}
Указатель освобождается перед вызовом на базу push_back
это нормально, потому что база push_back
Функция имеет строгую гарантию, что она удалит указатель, если возникнет исключение.
Перенос объекта из auto_ptr освобождает этот auto_ptr контроль над объектом. Это больше не получает преимущества auto_ptr. Вам нужно было бы поместить объект в другой интеллектуальный указатель, чтобы снова стать безопасным для исключений, или в контейнерный объект, который дает гарантии безопасности исключений (если они есть?).
Обратите внимание, что std::auto_ptr нельзя использовать непосредственно в контейнерах STL. Например, std:: vector