unique_ptr& operator=(unique_ptr&& u) noexcept; // (1) C++11
constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; // (1) C++23
template <class U, class E>
unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; // (2) C++11 単一オブジェクト版
// (2) C++17 配列版
template <class U, class E>
constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; // (2) C++23
unique_ptr& operator=(nullptr_t) noexcept; // (3) C++11
constexpr unique_ptr& operator=(nullptr_t) noexcept; // (3) C++23
unique_ptr& operator=(const unique_ptr&) = delete; // (4) C++11
概要
- (1) : 自身が保持しているリソースを解放し、
uから*thisに所有権を譲渡する。 - (2) : 自身が保持しているリソースを解放し、変換可能な
uから*thisに所有権を譲渡する - (3) : 自身が保持しているリソースを解放する。
- (4) : コピー代入禁止。
テンプレートパラメータ制約
- (1) :
- C++20 :
is_move_assignable_v<D> == trueであること。
- C++20 :
- (2) 単一オブジェクト : 以下を全て満たすこと:
unique_ptr<U, E>::pointerが、pointerに暗黙変換可能な型であること。Uが配列型ではないこと。is_assignable_v<D&, E&&> == trueであること。
- (2) 配列 : 以下を全て満たすこと:
Uは配列型であること。*thisの型UPについて、UP::pointerとUP::element_type*が同じ型であること。uの型UPについて、UP::pointerとUP::element_type*が同じ型であること。unique_ptr<U, D>::element_type(*)[]からunique_ptr<T[], D>::element_type(*)[]へ変換可能であること。is_assignable_v<D&, E&&> == trueであること。
要件
- (1) : デリータの型
Dが、例外を投げずにムーブ構築可能であること。
効果
- (1), (2) :
reset(u.release());
d_ = std::forward<E>(u.get_deleter());
- (3) :
reset()
事後条件
戻り値
*this
例外
投げない
例
#include <cassert>
#include <memory>
#include <utility>
int main()
{
std::unique_ptr<int> p0(new int(3));
// (1) ムーブ代入
// p0の所有権をp1に譲渡する
std::unique_ptr<int> p1;
p1 = std::move(p0);
assert(*p1 == 3);
// (2) 変換可能な型からの所有権移動
// p1の所有権をp2に譲渡する
std::unique_ptr<const int> p2;
p2 = std::move(p1);
assert(*static_cast<const int*>(p2.get()) == 3);
// (3) リソース解放
std::unique_ptr<int> p3(new int(3));
p3 = nullptr;
assert(!p3);
}
出力
バージョン
言語
- C++11
処理系
- GCC: 4.4.7 (nullptr_tのオーバーロード以外) ✅, 4.6.4 ✅
- Clang: 3.0 ✅
- ICC: ?
- Visual C++: 2010 ✅, 2012 ✅, 2013 ✅
- 2010にはnullptr_tのオーバーロードがない。
- 2012までは、delete宣言に対応していないため、代わりにprivateで宣言のみ行う手法で代用されている。
参照
- LWG Issue 2047. Incorrect "mixed" move-assignment semantics of
unique_ptr - LWG 2246.
unique_ptrassignment effects w.r.t. deleter - LWG 2228: Missing SFINAE rule in unique_ptr templated assignment
- (2)のSFINAEルール不足の欠陥修正の提案文書
- LWG Issue 2899.
is_(nothrow_)move_constructibleandtuple,optionalandunique_ptr- C++20で、ムーブ代入演算子(1)が、デリータ型
Dがムーブ代入可能でない場合はオーバーロード解決に参加しないよう制約化された
- C++20で、ムーブ代入演算子(1)が、デリータ型
- P2273R3 Making
std::unique_ptrconstexpr - LWG Issue 3455. Incorrect Postconditions on
unique_ptrmove assignment