Spec-Zone.ru › C++

std::unique_ptr<T,Deleter>::operator=

unique_ptr& operator=( unique_ptr&& r ) noexcept;
(1) (constexpr начиная с C++23)
template< class U, class E >
unique_ptr& operator=( unique_ptr<U, E>&& r ) noexcept;
(2) (constexpr начиная с C++23)
unique_ptr& operator=( std::nullptr_t ) noexcept;
(3) (constexpr начиная с C++23)
unique_ptr& operator=( const unique_ptr& ) = delete;
(4)
1) Оператор перемещающего присваивания. Передаёт владение от r к *this, как если бы был вызван reset(r.release()), а затем get_deleter() было присвоено значение std::forward<Deleter>(r.get_deleter()).
Эта перегрузка участвует в разрешении перегрузки только если std::is_move_assignable<Deleter>::value является true.
Если Deleter не является ссылочным типом, поведение не определено, если
  • Deleter не удовлетворяет требованиям MoveAssignable или
  • присваивание get_deleter() из rvalue типа Deleter вызвало бы исключение.
В противном случае (если Deleter является ссылочным типом) поведение не определено, если
  • std::remove_reference<Deleter>::type не удовлетворяет требованиям CopyAssignable или
  • присваивание get_deleter() из lvalue типа Deleter вызвало бы исключение.
2) Оператор преобразующего присваивания. Передаёт владение от r к *this, как если бы был вызван reset(r.release()), а затем get_deleter() было присвоено значение std::forward<E>(r.get_deleter()).
Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:
  • std::is_assignable<Deleter&, E&&>::value является true.
  • Для основного шаблона выполняются все следующие условия:
    • U не является типом массива.
    • unique_ptr<U, E>::pointer неявно преобразуется в pointer, и.
  • Для специализации для массивов (unique_ptr<T[]>) выполняются все следующие условия:
    • U является типом массива.
    • pointer совпадает по типу с element_type*.
    • unique_ptr<U, E>::pointer совпадает по типу с unique_ptr<U, E>::element_type*.
    • unique_ptr<U, E>::element_type(*)[] преобразуется в element_type(*)[].
Если E не является ссылочным типом, поведение не определено, если присваивание get_deleter() из rvalue типа E некорректно или вызвало бы исключение.
В противном случае (если E является ссылочным типом) поведение не определено, если присваивание get_deleter() из lvalue типа E некорректно или вызвало бы исключение.
3) По существу эквивалентно вызову reset().
4) Оператор копирующего присваивания явно удалён.

Параметры

r - умный указатель, от которого будет передано владение

Возвращаемое значение

*this

Примечания

Поскольку unique_ptr — тип, допускающий только перемещение, его оператор присваивания принимает только аргументы типа rvalue (например, результат std::make_unique или переменную unique_ptr, к которой применён std::move).

Пример

#include <iostream>
#include <memory>
 
struct Foo
{
    int id;
    Foo(int id) : id(id) { std::cout << "Foo " << id << '\n'; }
    ~Foo() { std::cout << "~Foo " << id << '\n'; }
};

int main() 
{
    std::unique_ptr<Foo> p1(std::make_unique<Foo>(1));
    
    {
        std::cout << "Creating new Foo...\n";
        std::unique_ptr<Foo> p2(std::make_unique<Foo>(2));
        // p1 = p2; // Error ! can't copy unique_ptr
        p1 = std::move(p2);
        std::cout << "About to leave inner block...\n";
        
        // Foo instance will continue to live, 
        // despite p2 going out of scope
    }
    
    std::cout << "About to leave program...\n";
}

Вывод:

Foo 1
Creating new Foo...
Foo 2
~Foo 1
About to leave inner block...
About to leave program...
~Foo 2

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены ретроспективно к ранее опубликованным стандартам C++.

DR Применён к Поведение согласно опубликованной версии Корректное поведение
LWG 2047 C++11 для перегрузки (2) значение get_deleter() присваивалось из
std::forward<Deleter>(r.get_deleter())
исправлено на
std::forward<E>(r.get_deleter())
LWG 2118 C++11 unique_ptr<T[]>::operator=
отклонял преобразования квалификации
принимает
LWG 2228
(N4366)
C++11 в преобразующем операторе присваивания
отсутствовало ограничение на возможность присваивания
ограничение добавлено
LWG 2246 C++11 цель присваивания преобразованного
удаляющего объекта r не была указана
указана как get_deleter()
LWG 2899 C++11 оператор перемещающего присваивания не имел ограничений ограничения добавлены

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/memory/unique_ptr/operator%3D

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API