23 General utilities library [utilities]

23.11 Smart pointers [smartptr]

23.11.1 Class template unique_­ptr [unique.ptr]

A unique pointer - это объект, который владеет другим объектом и управляет этим другим объектом с помощью указателя. Точнее, уникальный указатель - это объект, u который хранит указатель на второй объект p и будет удален, p когда u сам будет уничтожен (например, при выходе из области видимости блока ([stmt.dcl])). В этом контексте u говорят own p.

Механизм , с помощью которого u распоряжается p известно как p«ы связаны deleter, функциональный объект , чей правильный вызов приводит к p» с соответствующим расположением ( как правило , его удаление).

Пусть обозначение u.p обозначает указатель, хранящийся в u, и пусть u.d обозначает связанный с ним удалитель. По запросу u может reset (заменить) u.p и u.d другим указателем и средством удаления, но должен должным образом удалить принадлежащий ему объект с помощью связанного средства удаления, прежде чем такая замена будет считаться завершенной.

Дополнительно u может по запросу transfer ownership на другой уникальный указатель u2. По завершении такой передачи выполняются следующие постусловия:

  • u2.p равно предварительной передаче u.p,

  • u.p равно nullptr, и

  • если u.d состояние сохранялось до передачи , такое состояние было переведено в u2.d.

Как и в случае сброса, он u2 должен должным образом избавиться от объекта, принадлежащего ему до передачи, через связанный с ним удалитель до передачи, прежде чем передача права собственности будет считаться завершенной. [ Note: Состояние удалителя никогда не нужно копировать, его нужно только перемещать или менять местами по мере передачи права собственности. ] end note

Каждый объект типа, U созданный из unique_­ptr шаблона, указанного в этом подпункте, имеет строгую семантику владения уникальным указателем, указанную выше. В частичном удовлетворении этой семантики каждое такое U есть MoveConstructible и MoveAssignable, но не является CopyConstructible ни CopyAssignable. Параметр шаблона T из unique_­ptr может быть неполным типом.

[ Note: Использование unique_­ptr включает обеспечение безопасности исключений для динамически выделяемой памяти, передачу права собственности на динамически выделяемую память функции и возврат динамически выделенной памяти из функции. ] end note

namespace std {
  template<class T> struct default_delete;
  template<class T> struct default_delete<T[]>;

  template<class T, class D = default_delete<T>> class unique_ptr;
  template<class T, class D> class unique_ptr<T[], D>;

  template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
  template<class T> unique_ptr<T> make_unique(size_t n);
  template<class T, class... Args> unspecified make_unique(Args&&...) = delete;

  template<class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

  template<class T1, class D1, class T2, class D2>
    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
  template<class T1, class D1, class T2, class D2>
    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

  template <class T, class D>
    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
  template <class T, class D>
    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
  template <class T, class D>
    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
  template <class T, class D>
    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
  template <class T, class D>
    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);

}

23.11.1.1 Default deleters [unique.ptr.dltr]

23.11.1.1.1 In general [unique.ptr.dltr.general]

Шаблон класса default_­delete служит средством удаления (политика уничтожения) по умолчанию для шаблона класса unique_­ptr.

Параметр шаблона T из default_­delete может быть неполным типом.

23.11.1.1.2 default_­delete [unique.ptr.dltr.dflt]

namespace std {
  template <class T> struct default_delete {
    constexpr default_delete() noexcept = default;
    template <class U> default_delete(const default_delete<U>&) noexcept;
    void operator()(T*) const;
  };
}

template <class U> default_delete(const default_delete<U>& other) noexcept;

Effects: Создает default_­delete объект из другого default_­delete<U> объекта.

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки, если он не U* может быть неявно преобразован в T*.

void operator()(T* ptr) const;

Effects: Вызовы delete на ptr.

Remarks: Если T это неполный тип, программа плохо сформирована.

23.11.1.1.3 default_­delete<T[]> [unique.ptr.dltr.dflt1]

namespace std {
  template <class T> struct default_delete<T[]> {
    constexpr default_delete() noexcept = default;
    template <class U> default_delete(const default_delete<U[]>&) noexcept;
    template <class U> void operator()(U* ptr) const;
  };
}

template <class U> default_delete(const default_delete<U[]>& other) noexcept;

Effects: создает default_­delete объект из другого default_­delete<U[]> объекта.

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки, если он не U(*)[] может быть преобразован в T(*)[].

template <class U> void operator()(U* ptr) const;

Effects: Вызовы delete[] на ptr.

Remarks: Если U это неполный тип, программа плохо сформирована. Эта функция не должна участвовать в разрешении перегрузки, если U(*)[] она не может быть преобразована в T(*)[].

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-id remove_­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 это ссылочный тип lvalue A&, то подписи будут следующими:

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

Если D это ссылочный тип lvalue const 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() возвращает ссылку на lvalue d.

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.

23.11.1.3 unique_­ptr for array objects with a runtime length [unique.ptr.runtime]

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

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

    // destructor
    ~unique_ptr();

    // 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.runtime.observers], observers
    T& operator[](size_t i) const;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // [unique.ptr.runtime.modifiers], modifiers
    pointer release() noexcept;
    template <class U> void reset(U p) noexcept;
    void reset(nullptr_t = nullptr) noexcept;
    void swap(unique_ptr& u) noexcept;

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

Специализация для типов массивов предоставляется с немного измененным интерфейсом.

  • Преобразования между различными типами, unique_­ptr<T[], D> которые были бы запрещены для соответствующих типов указателей на массив, и преобразования в или из формunique_­ptr, не являющихся массивами , создают плохо сформированную программу.

  • Указатели на типы, производные от T , отклоняются конструкторами и reset.

  • Наблюдатели так operator* и operator-> не предусмотрены.

  • Предусмотрен обозреватель индексации operator[] .

  • Будет звонить средство удаления по умолчанию delete[].

Ниже приведены описания только для членов, которые отличаются от основного шаблона.

Аргумент шаблона T должен быть полного типа.

23.11.1.3.1 unique_­ptr constructors [unique.ptr.runtime.ctor]

template <class U> explicit unique_ptr(U p) noexcept;

Этот конструктор ведет себя так же, как конструктор в основном шаблоне, который принимает единственный параметр типа, pointer за исключением того, что он дополнительно не должен участвовать в разрешении перегрузки, если только

  • U того же типа, что и pointer, или

  • pointer имеет тот же тип element_­type*, U что и тип указателя V*, и V(*)[] может быть преобразован в element_­type(*)[].

template <class U> unique_ptr(U p, see below d) noexcept; template <class U> unique_ptr(U p, see below d) noexcept;

Эти конструкторы ведут себя так же, как конструкторы в основном шаблоне, которые принимают параметр типа pointer и второй параметр, за исключением того, что они не должны участвовать в разрешении перегрузки, если либо

  • U того же типа, что и pointer,

  • U есть nullptr_­t, или

  • pointer имеет тот же тип element_­type*, U что и тип указателя V*, и V(*)[] может быть преобразован в element_­type(*)[].

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

Этот конструктор ведет себя так же , как в первичном шаблоне, за исключением того, что она не будет участвовать в разрешении перегрузки , если все из следующих условий не выполняется, где UP находится unique_­ptr<U, E>:

  • U - это тип массива, а

  • pointer того же типа element_­type*, что и, и

  • UP​::​pointer того же типа UP​::​element_­type*, что и, и

  • UP​::​element_­type(*)[] конвертируется в element_­type(*)[], и

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

[ Note: Это заменяет спецификацию разрешения перегрузки основного шаблона ] end note

23.11.1.3.2 unique_­ptr assignment [unique.ptr.runtime.asgn]

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

Этот оператор ведет себя так же , как в первичном шаблоне, за исключением того, что она не будет участвовать в разрешении перегрузки , если все из следующих условий не выполняется, где UP находится unique_­ptr<U, E>:

  • U - это тип массива, а

  • pointer того же типа element_­type*, что и, и

  • UP​::​pointer того же типа UP​::​element_­type*, что и, и

  • UP​::​element_­type(*)[] конвертируется в element_­type(*)[], и

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

[ Note: Это заменяет спецификацию разрешения перегрузки основного шаблона ] end note

23.11.1.3.3 unique_­ptr observers [unique.ptr.runtime.observers]

T& operator[](size_t i) const;

Requires: i < количество элементов в массиве, на которые указывает сохраненный указатель.

Returns: get()[i].

23.11.1.3.4 unique_­ptr modifiers [unique.ptr.runtime.modifiers]

void reset(nullptr_t p = nullptr) noexcept;

Effects: Эквивалентно reset(pointer()).

template <class U> void reset(U p) noexcept;

Эта функция ведет себя так же, как reset член основного шаблона, за исключением того, что она не должна участвовать в разрешении перегрузки, если либо

  • U того же типа, что и pointer, или

  • pointer имеет тот же тип element_­type*, U что и тип указателя V*, и V(*)[] может быть преобразован в element_­type(*)[].

23.11.1.4 unique_­ptr creation [unique.ptr.create]

template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);

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

Returns: unique_­ptr<T>(new T(std​::​forward<Args>(args)...)).

template <class T> unique_ptr<T> make_unique(size_t n);

Remarks: Эта функция не должна участвовать в разрешении перегрузки, если только T это не массив с неизвестной границей.

Returns: unique_­ptr<T>(new remove_­extent_­t<T>[n]()).

template <class T, class... Args> unspecified make_unique(Args&&...) = delete;

Remarks: Эта функция не должна участвовать в разрешении перегрузки, если только T это не массив с известными границами.

23.11.1.5 unique_­ptr specialized algorithms [unique.ptr.special]

template <class T, class D> void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

Remarks: Эта функция не будет участвовать в разрешении перегрузки , если is_­swappable_­v<D> не true.

Effects: Звонки x.swap(y).

template <class T1, class D1, class T2, class D2> bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

Returns: x.get() == y.get().

template <class T1, class D1, class T2, class D2> bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

Returns: x.get() != y.get().

template <class T1, class D1, class T2, class D2> bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

Requires: Пусть CT обозначают

common_type_t<typename unique_ptr<T1, D1>::pointer,
              typename unique_ptr<T2, D2>::pointer>

Тогда специализация less<CT> должна быть a, function object type которая индуцирует a strict weak ordering для значений указателя.

Returns: less<CT>()(x.get(), y.get()).

Remarks: Если unique_­ptr<T1, D1>​::​pointer не может быть неявно преобразован CT или unique_­ptr<T2, D2>​::​pointer неявно преобразован в CT, программа имеет неправильный формат.

template <class T1, class D1, class T2, class D2> bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

Returns: !(y < x).

template <class T1, class D1, class T2, class D2> bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

Returns: y < x.

template <class T1, class D1, class T2, class D2> bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

Returns: !(x < y).

template <class T, class D> bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator==(nullptr_t, const unique_ptr<T, D>& x) noexcept;

Returns: !x.

template <class T, class D> bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; template <class T, class D> bool operator!=(nullptr_t, const unique_ptr<T, D>& x) noexcept;

Returns: (bool)x.

template <class T, class D> bool operator<(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<(nullptr_t, const unique_ptr<T, D>& x);

Requires: Специализация less<unique_­ptr<T, D>​::​pointer> должна быть a, function object type которая индуцирует a strict weak ordering для значений указателя.

Returns: Первый шаблон функции возвращается less<unique_­ptr<T, D>​::​pointer>()(x.get(),
nullptr)
. Второй шаблон функции возвращается less<unique_­ptr<T, D>​::​pointer>()(nullptr, x.get()).

template <class T, class D> bool operator>(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>(nullptr_t, const unique_ptr<T, D>& x);

Returns: Первый шаблон функции возвращается nullptr < x. Второй шаблон функции возвращается x < nullptr.

template <class T, class D> bool operator<=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator<=(nullptr_t, const unique_ptr<T, D>& x);

Returns: Первый шаблон функции возвращается !(nullptr < x). Второй шаблон функции возвращается !(x < nullptr).

template <class T, class D> bool operator>=(const unique_ptr<T, D>& x, nullptr_t); template <class T, class D> bool operator>=(nullptr_t, const unique_ptr<T, D>& x);

Returns: Первый шаблон функции возвращается !(x < nullptr). Второй шаблон функции возвращается !(nullptr < x).