std::unique_ptr<T,Deleter>::operator=
From cppreference.com
< cpp | memory | unique ptr
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()) を呼び出した後、r.get_deleter() を std::forward<Deleter>(r.get_deleter()) から代入するかのごとく転送します。 このオーバーロードは、
std::is_move_assignable<Deleter>::value が true の場合にのみオーバーロード解決に参加します。Deleter が参照型でない場合、以下のいずれかの条件を満たすと未定義動作となります。-
Deleterが MoveAssignable でない、または Deleter型の 右辺値 からget_deleter()を代入すると例外がスローされる。
それ以外の場合(
Deleter が参照型の場合)、以下のいずれかの条件を満たすと未定義動作となります。-
std::remove_reference<Deleter>::typeが CopyAssignable でない、または Deleter型の 左辺値 からget_deleter()を代入すると例外がスローされる。
2) 変換代入演算子。所有権を
r から *this へ、reset(r.release()) を呼び出した後、r.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(*)[]に変換可能である。
-
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 (N4366) |
C++11 | 変換代入演算子 代入可能制約が欠落していました |
制約を追加 |
| LWG 2246 | C++11 | 変換されたr のデリータの代入先が指定されていませんでした |
get_deleter() として指定 |
| LWG 2899 | C++11 | ムーブ代入演算子に制約がありませんでした | 制約付き |