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

履歴 編集

function
<optional>

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

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

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

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

template <class U = T>
EXPLICIT constexpr optional(U&& rhs);                    // (7)

template <class U>
EXPLICIT optional(const optional<U>& rhs);               // (8)

template <class U>
EXPLICIT optional(optional<U>&& rhs);                    // (9)

概要

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

効果

  • (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のムーブコンストラクタが任意の例外を送出する可能性がある
  • (5), (6), (7), (8), (9) : 型Tの選択されたコンストラクタが任意の例外を送出する可能性がある

備考

  • (3) :
    • Tがコピー構築可能でなければ、このオーバーロードはdelete定義される
    • Tがトリビアルにコピー構築可能であれば、このオーバーロードはconstexprとなる
  • (4) :
    • このオーバーロードのnoexceptの値は、is_nothrow_move_constructible_v<T>の値と同等になる
    • Tがムーブ構築可能でなければ、このオーバーロードはdelete定義される
    • Tがトリビアルにムーブ構築可能であれば、このオーバーロードはconstexprとなる
  • (5) :
    • Tの選択されたコンストラクタがconstexprであれば、このコンストラクタもconstexprとなる
    • Tが引数の型Args...から構築可能でなければ、このオーバーロードはオーバーロード解決の候補から除外される
    • std::in_place_tはオーバーロードに機能名を付けるためにあり、その型による動的な処理内容への影響はない。このオーバーロードを選択したい場合は、事前定義されている定数std::in_placeを第1引数として指定すること
  • (6) :
    • Tの選択されたコンストラクタがconstexprであれば、このコンストラクタもconstexprとなる
    • Tが引数の型initializer_list<U>&Args&&...から構築可能でなければ、このオーバーロードはオーバーロード解決の候補から除外される
  • (7) :
    • Tの選択されたコンストラクタがconstexprであれば、このコンストラクタもconstexprとなる
    • Uから型Tがムーブ構築可能でなければ、このオーバーロードはオーバーロード解決の候補から除外される
    • Uから型Tに暗黙的に型変換ができる場合、このオーバーロードは非explicitとなる。型Uから型Tに明示的な型変換ならできる場合、このオーバーロードはexplicitとなる
  • (8) :
    • Uから型Tがコピー構築可能でなければ、このオーバーロードはオーバーロード解決の候補から除外される
    • Uから型Tに暗黙的に型変換ができる場合、このオーバーロードは非explicitとなる。型Uから型Tに明示的な型変換ならできる場合、このオーバーロードはexplicitとなる
  • (9) :
    • Uから型Tがムーブ構築可能でなければ、このオーバーロードはオーバーロード解決の候補から除外される
    • Uから型Tに暗黙的に型変換ができる場合、このオーバーロードは非explicitとなる。型Uから型Tに明示的な型変換ならできる場合、このオーバーロードはexplicitとなる

#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

処理系

参照