跳到主要内容

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

声明

// 1)
constexpr unique_ptr& operator=( unique_ptr&& r ) noexcept;
// 2)
template< class U, class E >
constexpr unique_ptr& operator=( unique_ptr<U,E>&& r ) noexcept;
// 3)
constexpr unique_ptr& operator=( std::nullptr_t ) noexcept;

描述

1)

移动赋值运算符。通过调用 reset(r.release()) 然后从 std::forward<Deleter>(r.get_deleter()) 赋值 get_deleter() 来将所有权从 r 转移到 *this

如果 Deleter 不是引用类型,则要求它是 noexcept 的移动可赋值。如果 Deleter 是引用类型,则要求 std::remove_reference<Deleter>::type 是 noexcept 的复制可赋值。

当且仅当 std::is_move_assignable<Deleter>::valuetrue 时,移动赋值运算符才参与重载决议。

2)

转换赋值运算符。行为与 (1) 相同,但

  • 此主模板的赋值运算符仅当满足以下条件时才参与重载决议:U 不是数组类型,unique_ptr<U,E>::pointer 可隐式转换为 pointer,并且 std::is_assignable<Deleter&, E&&>::valuetrue

  • 此赋值运算符在数组特化 std::unique_ptr<T[]> 中,行为与主模板相同,但仅当以下所有条件都满足时才参与重载决议

    U 是数组类型
    pointerelement_type* 的类型相同
    unique_ptr<U,E>::pointerunique_ptr<U,E>::element_type* 的类型相同
    unique_ptr<U,E>::element_type(*)[] 可转换为 element_type(*)[]
    std::is_assignable<Deleter&, E&&>::valuetrue

3)

等同于调用 reset()。请注意,unique_ptr 的赋值运算符仅接受右值,这通常是通过 std::move 生成的。(unique_ptr 类显式删除了其左值复制构造函数和左值赋值运算符。)

参数

r - 将从中转移所有权的智能指针

返回值

*this

示例

#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

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

声明

// 1)
constexpr unique_ptr& operator=( unique_ptr&& r ) noexcept;
// 2)
template< class U, class E >
constexpr unique_ptr& operator=( unique_ptr<U,E>&& r ) noexcept;
// 3)
constexpr unique_ptr& operator=( std::nullptr_t ) noexcept;

描述

1)

移动赋值运算符。通过调用 reset(r.release()) 然后从 std::forward<Deleter>(r.get_deleter()) 赋值 get_deleter() 来将所有权从 r 转移到 *this

如果 Deleter 不是引用类型,则要求它是 noexcept 的移动可赋值。如果 Deleter 是引用类型,则要求 std::remove_reference<Deleter>::type 是 noexcept 的复制可赋值。

当且仅当 std::is_move_assignable<Deleter>::valuetrue 时,移动赋值运算符才参与重载决议。

2)

转换赋值运算符。行为与 (1) 相同,但

  • 此主模板的赋值运算符仅当满足以下条件时才参与重载决议:U 不是数组类型,unique_ptr<U,E>::pointer 可隐式转换为 pointer,并且 std::is_assignable<Deleter&, E&&>::valuetrue

  • 此赋值运算符在数组特化 std::unique_ptr<T[]> 中,行为与主模板相同,但仅当以下所有条件都满足时才参与重载决议

    U 是数组类型
    pointerelement_type* 的类型相同
    unique_ptr<U,E>::pointerunique_ptr<U,E>::element_type* 的类型相同
    unique_ptr<U,E>::element_type(*)[] 可转换为 element_type(*)[]
    std::is_assignable<Deleter&, E&&>::valuetrue

3)

等同于调用 reset()。请注意,unique_ptr 的赋值运算符仅接受右值,这通常是通过 std::move 生成的。(unique_ptr 类显式删除了其左值复制构造函数和左值赋值运算符。)

参数

r - 将从中转移所有权的智能指针

返回值

*this

示例

#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