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

履歴 編集

function
<optional>

std::optional::コンストラクタ(C++17)

constexpr optional() noexcept;                                  // (1) C++17
constexpr optional(nullopt_t) noexcept;                         // (2) C++17
constexpr optional(const optional& rhs);                        // (3) C++17
constexpr optional(optional&& rhs) noexcept(see below);         // (4) C++17

template <class... Args>
constexpr explicit optional(in_place_t, Args&&... args);        // (5) C++17

template <class U, class... Args>
constexpr explicit optional(
                     in_place_t,
                     initializer_list<U> il,
                     Args&&... args);                           // (6) C++17

template <class U = T>
EXPLICIT constexpr optional(U&& rhs);                           // (7) C++17
template <class U = T>
explicit(see below) constexpr optional(U&& rhs);                // (7) C++20

template <class U>
EXPLICIT optional(const optional<U>& rhs);                      // (8) C++17
template <class U>
explicit(see below) optional(const optional<U>& rhs);           // (8) C++20
template <class U>
explicit(see below) constexpr optional(const optional<U>& rhs); // (8) C++23

template <class U>
EXPLICIT optional(optional<U>&& rhs);                           // (9) C++17
template <class U>
explicit(see below) optional(optional<U>&& rhs);                // (9) C++20
template <class U>
explicit(see below) constexpr optional(optional<U>&& rhs);      // (9) C++23

概要

  • (1), (2) : 有効値を保持していない状態にする
  • (3) : コピーコンストラクタ
  • (4) : ムーブコンストラクタ
  • (5) : 型Tのコンストラクタ引数を受け取って、コンストラクタ内で型Tのオブジェクトを有効値として生成し、保持する
  • (6) : 型Tのコンストラクタ引数として初期化子リストと任意個の引数を受け取って、コンストラクタ内で型Tのオブジェクトを有効値として生成し、保持する
  • (7) : 型Tに変換可能な型Uの値を有効値として受け取り、ムーブして保持する
  • (8) : 変換可能なoptionalオブジェクトからコピー構築する
  • (9) : 変換可能なoptionalオブジェクトからムーブ構築する

テンプレートパラメータ制約

  • (5) : 型Tが引数の型Args...から構築可能であること
  • (6) : 型Tが引数の型initializer_list<U>&Args&&...から構築可能であること
  • (7) : 型Uから型Tがムーブ構築可能であること
  • (8) : 型Uから型Tがコピー構築可能であること
  • (9) : 型Uから型Tがムーブ構築可能であること

効果

  • (1), (2) : 有効値を保持していない状態にする。このとき、有効値の型Tのオブジェクトは構築されない
  • (3) : rhsが有効値を保持していれば、それを*thisにコピーする
  • (4) : rhsが有効値を保持していれば、それを*thisにムーブする。rhs.has_value()は変更されない
  • (5) : 可変個の引数args...を型Tのコンストラクタ引数として転送して、コンストラクタ内で型Tの有効値を構築して保持する
  • (6) : 初期化子リストilと可変個の引数args...を型Tのコンストラクタ引数として転送して、コンストラクタ内で型Tの有効値を構築して保持する
  • (7) : rhsを有効値として、*thisにムーブする
  • (8) : rhsが有効値を保持していれば、それを*thisにコピーする
  • (9) : rhsが有効値を保持していれば、それを*thisにムーブする

例外

  • (3) :
    • Tのコピーコンストラクタが任意の例外を送出する可能性がある
  • (4) :
    • Tのムーブコンストラクタが任意の例外を送出する可能性がある
    • このオーバーロードのnoexceptの値は、is_nothrow_move_constructible_v<T>の値と等価になる
  • (5), (6), (7), (8), (9) :
    • Tの選択されたコンストラクタが任意の例外を送出する可能性がある

delete定義される条件

  • (3) : 型Tがコピー構築可能でないこと
  • (4) : 型Tがムーブ構築可能でないこと

定数式に評価される条件

トリビアルに定義される条件

explicitになる条件

  • (7) : 型Uから型Tに暗黙的に型変換ができる場合、このオーバーロードは非explicitとなる。型Uから型Tに明示的な型変換ならできる場合、このオーバーロードはexplicitとなる
  • (8) : 型Uから型Tに暗黙的に型変換ができる場合、このオーバーロードは非explicitとなる。型Uから型Tに明示的な型変換ならできる場合、このオーバーロードはexplicitとなる
  • (9) : 型Uから型Tに暗黙的に型変換ができる場合、このオーバーロードは非explicitとなる。型Uから型Tに明示的な型変換ならできる場合、このオーバーロードはexplicitとなる

備考

  • (5) : std::in_place_tはオーバーロードに機能名を付けるためにあり、その型による動的な処理内容への影響はない。このオーバーロードを選択したい場合は、事前定義されている定数std::in_placeを第1引数として指定すること

#include <cassert>
#include <optional>
#include <string>
#include <vector>
#include <memory>

struct Base {};
struct Derived : Base {};

int main()
{
  // (1)
  {
    std::optional<int> p;
    assert(!p.has_value());
  }

  // (2)
  {
    std::optional<int> p = std::nullopt;
    assert(!p.has_value());
  }

  // (3)
  {
    std::optional<int> a = 3;
    std::optional<int> b = a;

    assert(a.value() == 3);
    assert(b.value() == 3);
  }

  // (4)
  {
    std::optional<std::string> a = "Hello";
    std::optional<std::string> b = std::move(a);

    assert(b.value() == "Hello");
  }

  // (5)
  {
    std::optional<std::string> p {std::in_place, 3, 'A'};
    assert(p.value() == "AAA");
  }

  // (6)
  {
    std::allocator<int> alloc;
    std::optional<std::vector<int>> p {std::in_place, {3, 1, 4}, alloc};

    assert(p.value()[0] == 3);
    assert(p.value()[1] == 1);
    assert(p.value()[2] == 4);
  }

  // (7)
  {
    // const char*からstd::stringに暗黙的に型変換
    std::optional<std::string> p1 = "Hello";
    assert(p1.value() == "Hello");

    // 整数値からstd::vectorに明示的に型変換
    std::optional<std::vector<int>> p2 {3};
    assert(p2.value().size() == 3);
  }

  // (8)
  {
    std::optional<const char*> a = "Hello";
    std::optional<std::string> b = a;

    assert(b.value() == "Hello");
  }

  // (9)
  {
    std::optional<std::shared_ptr<Derived>> a = std::make_shared<Derived>();
    std::optional<std::shared_ptr<Base>> b = std::move(a);
  }
}

出力

バージョン

言語

  • C++17

処理系

関連項目

参照