- memory[meta header]
- std[meta namespace]
- unique_ptr[meta class]
- function[meta id-type]
- cpp11[meta cpp]
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
- nullptr_t[link /reference/cstddef/nullptr_t.md]
- (1) : 自身が保持しているリソースを解放し、
u
から*this
に所有権を譲渡する。 - (2) : 自身が保持しているリソースを解放し、変換可能な
u
から*this
に所有権を譲渡する - (3) : 自身が保持しているリソースを解放する。
- (4) : コピー代入禁止。
- (1) : デリータの型
D
が、例外を投げずにムーブ構築可能であること。 - (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), (2) :
reset(u.release());
d_ = std::forward<E>(u.get_deleter());
- reset[link reset.md]
- release[link release.md]
- std::forward[link /reference/utility/forward.md]
- get_deleter()[link get_deleter.md]
- (3) :
reset()
*this
投げない
#include <cassert>
#include <memory>
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);
}
- std::move[link /reference/utility/move.md]
- C++11
- GCC: 4.4.7 (nullptr_tのオーバーロード以外) [mark verified], 4.6.4 [mark verified]
- Clang: 3.0 [mark verified]
- ICC: ?
- Visual C++: 2010 [mark verified], 2012 [mark verified], 2013 [mark verified]
- 2010にはnullptr_tのオーバーロードがない。
- 2012までは、delete宣言に対応していないため、代わりにprivateで宣言のみ行う手法で代用されている。