最終更新日時(UTC):
が更新

履歴 編集

function
<memory>

std::unique_ptr::operator=(C++11)

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) : デリータの型Dが、例外を投げずにムーブ構築可能であること。
  • (2) 単一オブジェクト : 以下の条件を満たさない場合、この関数はオーバーロード解決の候補から外れる:
    • unique_ptr<U, E>::pointerが、pointerに暗黙変換可能な型であること。
    • Uが配列型ではないこと。
    • is_assignable_v<D&, E&&> == trueであること。
  • (2) 配列 : 以下の条件を満たさない場合、この関数はオーバーロード解決の候補から外れる:
    • Uは配列型であること。
    • *thisの型UPについて、UP::pointerUP::element_type*が同じ型であること。
    • uの型UPについて、UP::pointerUP::element_type*が同じ型であること。
    • unique_ptr<U, D>::element_type(*)[]からunique_ptr<T[], D>::element_type(*)[]へ変換可能であること。
    • is_assignable_v<D&, E&&> == trueであること。

効果

  • (1), (2) :

戻り値

*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);
}

出力

バージョン

言語

  • 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で宣言のみ行う手法で代用されている。

参照