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() из справа от знака присваивания типа Deleter вызовет исключение.
В противном случае (Deleter является типом-ссылкой), поведение является неопределённым, если
  • std::remove_reference<Deleter>::type не является CopyAssignable, или
  • присвоение get_deleter() из слева от знака присваивания типа Deleter вызовет исключение.
2) Оператор преобразования присваивания. Передаёт владение от r к *this как если бы вызов reset(r.release()) был выполнен, а затем get_deleter() было присвоено из std::forward<E>(r.get_deleter()).
Для основной шаблона этот перегруз участвует в разрешении перегрузки только если
  • U не является типом-массивом,
  • unique_ptr<U, E>::pointer неявно преобразуется к pointer, и
  • std::is_assignable<Deleter&, E&&>::value является true.
Для специализации массива (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(*)[], и
  • std::is_assignable<Deleter&, E&&>::value является true.
Если E не является типом-ссылкой, поведение является неопределённым, если присвоение get_deleter() из справа от знака присваивания типа E недопустимо или вызовет исключение.
В противном случае (E является типом-ссылкой), поведение является неопределённым, если присвоение get_deleter() из слева от знака присваивания типа E недопустимо или вызовет исключение.
3) Эквивалентно вызову reset().
4) Оператор копирования присваивания явно удалён.

Параметры

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

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

*this

Примечания

В качестве типа, допускающего только перемещение, оператор присваивания unique_ptr принимает только аргументы справа от знака присваивания (например, результат std::make_unique или переменную std::move, содержащую unique_ptr).

Пример

#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 C++11 оператор преобразования присваивания не был ограничен ограничен
LWG 2899 C++11 оператор перемещения присваивания не был ограничен ограничен

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

Spec-Zone.ru

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