23 General utilities library [utilities]

23.11 Smart pointers [smartptr]

23.11.1 Class template unique_­ptr [unique.ptr]

23.11.1.2 unique_­ptr for single objects [unique.ptr.single]

namespace std {
  template <class T, class D = default_delete<T>> class unique_ptr {
  public:
    using pointer      = see below;
    using element_type = T;
    using deleter_type = D;

    // [unique.ptr.single.ctor], constructors
    constexpr unique_ptr() noexcept;
    explicit unique_ptr(pointer p) noexcept;
    unique_ptr(pointer p, see below d1) noexcept;
    unique_ptr(pointer p, see below d2) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    constexpr unique_ptr(nullptr_t) noexcept;
    template <class U, class E>
      unique_ptr(unique_ptr<U, E>&& u) noexcept;

    // [unique.ptr.single.dtor], destructor
    ~unique_ptr();

    // [unique.ptr.single.asgn], assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // [unique.ptr.single.observers], observers
    add_lvalue_reference_t<T> operator*() const;
    pointer operator->() const noexcept;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // [unique.ptr.single.modifiers], modifiers
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    void swap(unique_ptr& u) noexcept;

    // disable copy from lvalue
    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;
  };
}

Тип по умолчанию для параметра шаблонаD - default_­delete. Аргумент шаблона, предоставляемый клиентом, D должен быть function object typeссылкой lvalue на функцию или ссылкой lvalue на тип объекта функции, для которого, учитывая значениеd типаD и значение ptr типаunique_­ptr<T, D>​::​pointer, выражение d(ptr) является действительным и имеет эффект удаления указателя как подходит для этого удалителя.

Если тип удалителяD не является ссылочным типом, онD должен удовлетворять требованиямDestructible.

Если qualified-idremove_­reference_­t<D>​::​pointer действительно и обозначает тип ([temp.deduct]), тоunique_­ptr<T, D>​::​pointer должно быть синонимом дляremove_­reference_­t<D>​::​pointer. В противном случае unique_­ptr<T, D>​::​pointer будет синонимомelement_­type*. Типunique_­ptr<T, D>​::​pointer должен удовлетворять требованиямNullablePointer.

[ Example: Принимая во внимание тип распределителяX ([allocator.requirements]) и позволяяA быть синонимомallocator_­traits<X>, типовA​::​pointer, A​::​const_­pointer,A​::​void_­pointerиA​::​const_­void_­pointer могут быть использованы в качествеunique_­ptr<T, D>​::​pointer. ]end example

23.11.1.2.1 unique_­ptr constructors [unique.ptr.single.ctor]

constexpr unique_ptr() noexcept; constexpr unique_ptr(nullptr_t) noexcept;

Requires:D должны удовлетворять требованиямDefaultConstructible, и эта конструкция не должна вызывать исключения.

Effects: Создаетunique_­ptr объект, который ничего не владеет, инициализируя значение сохраненного указателя и сохраненного средства удаления.

Postconditions:get() == nullptr.get_­deleter() возвращает ссылку на сохраненный удалитель.

Remarks: Еслиis_­pointer_­v<deleter_­type> естьtrue или is_­default_­constructible_­v<deleter_­type> естьfalse, этот конструктор не должен участвовать в разрешении перегрузки.

explicit unique_ptr(pointer p) noexcept;

Requires:D должны удовлетворять требованиямDefaultConstructible, и эта конструкция не должна вызывать исключения.

Effects: Создает объект,unique_­ptr который владеет p, инициализируя сохраненный указательp и инициализируя значение сохраненного средства удаления.

Postconditions:get() == p.get_­deleter() возвращает ссылку на сохраненный удалитель.

Remarks: Еслиis_­pointer_­v<deleter_­type> естьtrue или is_­default_­constructible_­v<deleter_­type> естьfalse, этот конструктор не должен участвовать в разрешении перегрузки. Если deduction ([over.match.class.deduct]) аргумента шаблона класса выберет шаблон функции, соответствующий этому конструктору, то программа сформирована неправильно.

unique_ptr(pointer p, see below d1) noexcept; unique_ptr(pointer p, see below d2) noexcept;

Подпись этих конструкторов зависит от того,D является ли это ссылочным типом. ЕслиD это не ссылочный тип A, то подписи:

unique_ptr(pointer p, const A& d) noexcept;
unique_ptr(pointer p, A&& d) noexcept;

ЕслиD это ссылочный тип lvalueA&, то подписи будут следующими:

unique_ptr(pointer p, A& d) noexcept;
unique_ptr(pointer p, A&& d) = delete;

ЕслиD это ссылочный тип lvalueconst A&, то подписи будут следующими:

unique_ptr(pointer p, const A& d) noexcept;
unique_ptr(pointer p, const A&& d) = delete;

Effects: Создаетunique_­ptr объект, которому принадлежитp, инициализируя сохраненный указательp и инициализируя средство удаления изstd​::​forward<decltype(d)>(d).

Remarks: Эти конструкторы не должны участвовать в разрешении перегрузки , еслиis_­constructible_­v<D, decltype(d)> неtrue.

Postconditions:get() == p. get_­deleter() возвращает ссылку на сохраненный удалитель. ЕслиD является ссылочным типом,get_­deleter() возвращает ссылку на lvalued.

Remarks: Если аргумент deduction ([over.match.class.deduct]) шаблона класса выберет шаблон функции, соответствующий любому из этих конструкторов, то программа сформирована неправильно.

[Example:

D d;
unique_ptr<int, D> p1(new int, D());        // D must be MoveConstructible
unique_ptr<int, D> p2(new int, d);          // D must be CopyConstructible
unique_ptr<int, D&> p3(new int, d);         // p3 holds a reference to d
unique_ptr<int, const D&> p4(new int, D()); // error: rvalue deleter object combined
                                            // with reference deleter type

end example]

unique_ptr(unique_ptr&& u) noexcept;

Requires: ЕслиD не является эталонным типом, он D должен удовлетворять требованиям MoveConstructible. Построение удалителя из rvalue типаD не должно вызывать исключения.

Effects: Создаетunique_­ptr путем передачи права собственности от u к*this. ЕслиD это ссылочный тип, это средство удаления является копией, созданной из средстваuудаления; в противном случае этот удалительuсоздается на основе удалителя. [ Note: Конструктор удаления может быть реализован с помощьюstd​::​forward<D>. ]end note

Postconditions:get() дает значение,u.get() полученное до строительства.get_­deleter() возвращает ссылку на сохраненный удалитель, созданный из u.get_­deleter(). ЕслиD это ссылочный тип, то оба ссылаются на одинget_­deleter() иu.get_­deleter() тот же удалитель lvalue.

template <class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;

Requires: ЕслиE это не ссылочный тип, построение удалителя из rvalue типа E должно быть правильно сформировано и не должно вызывать исключения. В противном случаеE является ссылочным типом, и конструкция удалителя из lvalue типаE должна быть правильно сформирована и не должна вызывать исключения.

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки, если:

  • unique_­ptr<U, E>​::​pointer неявно конвертируется вpointer,

  • U не является типом массива и

  • либоD является ссылочным типом иE относится к тому же типуD, либо D не является ссылочным типом иE может неявно преобразовываться вD.

Effects: Создаетunique_­ptr путем передачи права собственности отu к*this. ЕслиE это ссылочный тип, это средство удаления является копией, созданной из средства uудаления; в противном случае этот удалительuсоздается на основе удалителя. [ Note: Конструктор удаления может быть реализован с помощью std​::​forward<E>. ]end note

Postconditions:get() дает значение,u.get() полученное до строительства. get_­deleter() возвращает ссылку на сохраненный удалитель, созданный из u.get_­deleter().

23.11.1.2.2 unique_­ptr destructor [unique.ptr.single.dtor]

~unique_ptr();

Requires: Выражениеget_­deleter()(get()) должно быть правильно сформировано, иметь четко определенное поведение и не должно вызывать исключений. [ Note: Использованиеdefault_­delete требуетT полного типа. ]end note

Effects: Еслиget() == nullptr нет эффектов. В противном случаеget_­deleter()(get()).

23.11.1.2.3 unique_­ptr assignment [unique.ptr.single.asgn]

unique_ptr& operator=(unique_ptr&& u) noexcept;

Requires: ЕслиD не является ссылочным типом, онD должен удовлетворять требованиям,MoveAssignable и назначение удалителя из rvalue типаD не должно вызывать исключения. В противном случаеD - ссылочный тип; remove_­reference_­t<D> должен удовлетворятьCopyAssignable требованиям, и назначение удалителя из lvalue типаD не должно вызывать исключения.

Effects: Передает право собственности отu к,*this как если бы при звонке с reset(u.release()) последующим get_­deleter() = std​::​forward<D>(u.get_­deleter()).

Returns:*this.

template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;

Requires: ЕслиE это не ссылочный тип, назначение удалителя из rvalue типаE должно быть правильно сформированным и не должно вызывать исключения. В противном случаеE - это ссылочный тип, и назначение удалителя из lvalue типаE должно быть правильно сформированным и не должно вызывать исключения.

Remarks: Этот оператор не должен участвовать в разрешении перегрузки, если:

  • unique_­ptr<U, E>​::​pointer неявно конвертируется вpointer, и

  • U не является типом массива и

  • is_­assignable_­v<D&, E&&> естьtrue.

Effects: Передает право собственности отu к,*this как если бы при звонке с reset(u.release()) последующим get_­deleter() = std​::​forward<E>(u.get_­deleter()).

Returns:*this.

unique_ptr& operator=(nullptr_t) noexcept;

Effects: Как будто мимоreset().

Postconditions:get() == nullptr.

Returns:*this.

23.11.1.2.4 unique_­ptr observers [unique.ptr.single.observers]

add_lvalue_reference_t<T> operator*() const;

Requires:get() != nullptr.

Returns:*get().

pointer operator->() const noexcept;

Requires:get() != nullptr.

Returns:get().

[ Note: Для использования этой функции обычно требуетсяT полный тип. ] end note

pointer get() const noexcept;

Returns: Сохраненный указатель.

deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept;

Returns: Ссылка на сохраненный удалитель.

explicit operator bool() const noexcept;

Returns:get() != nullptr.

23.11.1.2.5 unique_­ptr modifiers [unique.ptr.single.modifiers]

pointer release() noexcept;

Postconditions:get() == nullptr.

Returns: Значениеget() было в начале вызоваrelease.

void reset(pointer p = pointer()) noexcept;

Requires: Выражениеget_­deleter()(get()) должно быть правильно сформировано, иметь четко определенное поведение и не должно вызывать исключений.

Effects: Присваиваетсяp сохраненному указателю, и затем, если и только если старое значение сохраненного указателя,old_­pне было равноnullptr, вызывает get_­deleter()(old_­p). [ Note: Порядок этих операций важен, потому что вызовget_­deleter() может уничтожить*this. ]end note

Postconditions:get() == p. [ Note: Постусловие не выполняется, если вызовget_­deleter() уничтожает,*this посколькуthis->get() больше не является допустимым выражением. ] end note

void swap(unique_ptr& u) noexcept;

Requires:get_­deleter() должно бытьswappable и не должно вызывать исключениеswap.

Effects: Вызываетswap сохраненные указатели и сохраненные удалители*this иu.