名前空間
変種
操作

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

From cppreference.com
< cpp‎ | memory‎ | unique ptr
 
 
メモリ管理ライブラリ
(説明用*)
未初期化メモリのアルゴリズム
(C++17)
(C++17)
(C++17)
制約付き未初期化
メモリアルゴリズム
Cライブラリ

アロケータ
メモリリソース
ガベージコレクションのサポート
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
未初期化ストレージ
(C++20まで*)
(C++20まで*)
明示的な生存期間管理
 
 
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>::valuetrue の場合にのみオーバーロード解決に参加します。
Deleter が参照型でない場合、以下のいずれかの条件を満たすと未定義動作となります。
  • DeleterMoveAssignable でない、または
  • Deleter 型の 右辺値 から get_deleter() を代入すると例外がスローされる。
それ以外の場合(Deleter が参照型の場合)、以下のいずれかの条件を満たすと未定義動作となります。
  • std::remove_reference<Deleter>::typeCopyAssignable でない、または
  • Deleter 型の 左辺値 から get_deleter() を代入すると例外がスローされる。
2) 変換代入演算子。所有権を r から *this へ、reset(r.release()) を呼び出した後、r.get_deleter()std::forward<E>(r.get_deleter()) から代入するかのごとく転送します。
このオーバーロードは、以下のすべての条件が満たされた場合にのみオーバーロード解決に参加します。
  • std::is_assignable<Deleter&, E&&>::valuetrue
  • プライマリテンプレートの場合、以下のすべての条件が満たされます。
    • U が配列型でない。
    • unique_ptr<U, E>::pointerpointer に暗黙変換可能である。
  • 配列特殊化(unique_ptr<T[]>)の場合、以下のすべての条件が満たされます。
    • U が配列型である。
    • pointerelement_type* と同じ型である。
    • unique_ptr<U, E>::pointerunique_ptr<U, E>::element_type* と同じ型である。
    • unique_ptr<U, E>::element_type(*)[]element_type(*)[] に変換可能である。
E が参照型でない場合、`get_deleter()` を型 E右辺値 から代入することがill-formedであるか、または例外をスローする場合、未定義動作となります。
それ以外の場合(E が参照型の場合)、`get_deleter()` を型 E左辺値 から代入することがill-formedであるか、または例外をスローする場合、未定義動作となります。
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 ムーブ代入演算子に制約がありませんでした 制約付き
English 日本語 中文(简体) 中文(繁體)