Namespaces
Variants

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

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
unique_ptr & operator = ( unique_ptr && r ) noexcept ;
(1) (自 C++23 起为 constexpr)
template < class U, class E >
unique_ptr & operator = ( unique_ptr < U, E > && r ) noexcept ;
(2) (自 C++23 起为 constexpr)
unique_ptr & operator = ( std:: nullptr_t ) noexcept ;
(3) (自 C++23 起为 constexpr)
unique_ptr & operator = ( const unique_ptr & ) = delete ;
(4)
1) 移动赋值运算符。将所有权从 r 转移至 * this ,操作方式类似于先调用 reset ( r. release ( ) ) ,随后通过 std:: forward < Deleter > ( r. get_deleter ( ) ) 赋值 get_deleter()
此重载仅当 std:: is_move_assignable < Deleter > :: value true 时参与重载决议。
如果 Deleter 不是引用类型,则在以下情况下行为未定义:
否则( 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 不是引用类型,当从类型 E 右值 赋值 get_deleter() 的行为非法或会抛出异常时,其行为未定义。
否则( E 是引用类型),如果从类型 E 左值 赋值 get_deleter() 是病式的或会抛出异常,则行为未定义。
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; // 错误!无法复制 unique_ptr
        p1 = std::move(p2);
        std::cout << "About to leave inner block...\n";
        // Foo 实例将继续存在,
        // 即使 p2 离开作用域
    }
    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++ 标准。

缺陷报告 适用版本 发布时行为 正确行为
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 移动赋值运算符未受约束 添加了约束