名前空間
変種
操作

std::optional<T>::optional

From cppreference.com
< cpp‎ | utility‎ | optional
 
 
ユーティリティライブラリ
言語サポート
型のサポート (基本型、RTTI)
ライブラリ機能検査マクロ (C++20)
プログラムユーティリティ
可変引数関数
コルーチンサポート (C++20)
契約サポート (C++26)
三方比較
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

汎用ユーティリティ
関係演算子 (C++20で非推奨)
 
 
constexpr optional() noexcept;
(1) (C++17以降)
constexpr optional( std::nullopt_t ) noexcept;
(2) (C++17以降)
constexpr optional( const optional& other );
(3) (C++17以降)
constexpr optional( optional&& other ) noexcept(/* 下記参照 */);
(4) (C++17以降)
template< class U >
optional( const optional<U>& other );
(5) (C++17以降)
(C++20 以降 constexpr)
(条件付き explicit)
template< class U >
optional( optional<U>&& other );
(6) (C++17以降)
(C++20 以降 constexpr)
(条件付き explicit)
template< class... Args >
constexpr explicit optional( std::in_place_t, Args&&... args );
(7) (C++17以降)
template< class U, class... Args >

constexpr explicit optional( std::in_place_t,
                             std::initializer_list<U> ilist,

                             Args&&... args );
(8) (C++17以降)
template< class U = std::remove_cv_t<T> >
constexpr optional( U&& value );
(9) (C++17以降)
(条件付き explicit)

新しいoptionalオブジェクトを構築します。

目次

[編集] パラメータ

その他 - 別のoptionalオブジェクト。その格納されている値はコピーされます。
value - 含まれる値を初期化するための値
args... - 含まれる値を初期化するための引数
ilist - 含まれる値を初期化するための初期化子リスト

[編集] 効果

 オーバーロード  初期化方法 格納されている値の初期化子 構築後のhas_value()
(1) N/A - false
(2)
(3) 直接(リスト以外) *other other.has_value()
  • 格納されている値は初期化されません(falseの場合)。
(4) std::move(*other)
(5) *other
(6) std::move(*other)
(7) std::forward<Args>(args)... true
(8) ilist, std::forward<Args>(args)...
(9) std::forward<U>(value)

[編集] 制約と補足情報

3) std::is_copy_constructible_v<T>false の場合、コンストラクタは削除されたものとして定義されます。
std::is_trivially_copy_constructible_v<T>true の場合、コンストラクタはトリビアルです。
4) このオーバーロードは、std::is_move_constructible_v<T>true の場合にのみ、オーバーロード解決に参加します。
std::is_trivially_move_constructible_v<T>true の場合、コンストラクタはトリビアルです。
5) このオーバーロードは、以下のすべての条件が満たされている場合にのみ、オーバーロード解決に参加します。
このオーバーロードは、explicit(!std::is_convertible_v<const U&, T>) で宣言されているかのように扱われます。
6) このオーバーロードは、以下のすべての条件が満たされている場合にのみ、オーバーロード解決に参加します。
このオーバーロードは、explicit(!std::is_convertible_v<U, T>) で宣言されているかのように扱われます。
7) このオーバーロードは、std::is_constructible_v<T, Args...>true の場合にのみ、オーバーロード解決に参加します。
Tの初期化に選択されたコンストラクタが constexpr コンストラクタの場合、このコンストラクタも constexpr コンストラクタになります。
8) このオーバーロードは、std::is_constructible_v<T, std::initializer_list<U>&, Args...>true の場合にのみ、オーバーロード解決に参加します。
Tの初期化に選択されたコンストラクタが constexpr コンストラクタの場合、このコンストラクタも constexpr コンストラクタになります。
9) このオーバーロードは、以下のすべての条件が満たされている場合にのみ、オーバーロード解決に参加します。
このオーバーロードは、explicit(!std::is_convertible_v<U, T>) で宣言されているかのように扱われます。
Tの初期化に選択されたコンストラクタが constexpr コンストラクタの場合、このコンストラクタも constexpr コンストラクタになります。
  1. 1.0 1.1 言い換えると、Tは、(cv修飾されている可能性のある)std::optional<U> の型の式(cv修飾されている可能性あり)から構築も変換もできません。

[編集] 例外

3) Tのコンストラクタによってスローされる例外をスローします。
4) Tのコンストラクタによってスローされる例外をスローします。以下の例外仕様を持ちます。
noexcept 指定:  
5-9) Tのコンストラクタによってスローされる例外をスローします。

[編集] 推論ガイド

[編集] 注意

LWG issue 3836 の解決前は、std::optional<bool>std::optional<U> から構築する場合、Ubool でない場合、オーバーロード (5,6) がオーバーロード解決に参加しないため、オーバーロード (9) が選択されていました。これは、オーバーロード (5,6) が、T(この場合は bool)が std::optional<U> から構築または変換できる場合に参加しないという制約があったためです。しかし、std::optional::operator bool により、任意の U に対して変換が可能になっていました。

その結果、構築された std::optional<bool> は常に値を含んでいました。その値は、提供された std::optional<U> オブジェクトが値を含むかどうかによって決まり、格納されている値から直接初期化された bool 値ではありませんでした。

std::optional<bool> op_false(false);
std::optional<int> op_zero(0);
 
std::optional<int> from_bool(op_false); // OK: contains 0 (initialized from false)
std::optional<bool> from_int(op_zero);  // DEFECT (LWG 3836): contains true because
                                        // op_zero contains a value, even if initializing
                                        // bool from that value gives false
機能テストマクロ 規格 機能
__cpp_lib_optional 202106L (C++20)
(DR20)
完全に constexpr(5,6)

[編集]

#include <iostream>
#include <optional>
#include <string>
 
int main()
{
    std::optional<int> o1, // empty
                       o2 = 1, // init from rvalue
                       o3 = o2; // copy-constructor
 
    // calls std::string( initializer_list<CharT> ) constructor
    std::optional<std::string> o4(std::in_place, {'a', 'b', 'c'});
 
    // calls std::string( size_type count, CharT ch ) constructor
    std::optional<std::string> o5(std::in_place, 3, 'A');
 
    // Move-constructed from std::string using deduction guide to pick the type
 
    std::optional o6(std::string{"deduction"});
 
    std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << ' ' << *o5  << ' ' << *o6 << '\n';
}

出力

1 1 abc AAA deduction

[編集] 欠陥レポート

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 3836 C++17 std::optional<bool> を構築する際
std::optional<U> から、オーバーロード解決は
Ubool でない場合、オーバーロード (9) を選択する
常に
変換コピー/ムーブ
この場合の
LWG 3886 C++17 オーバーロード (9) のデフォルトテンプレート引数は T であった std::remove_cv_t<T>に変更されました。
P0602R4 C++17 コピー/ムーブコンストラクタはトリビアルではない場合がある
基になるコンストラクタがトリビアルであっても
必要とされる
トリビアル性の伝播
P2231R1 C++20 別のstd::optionalからのオーバーロード (5,6)constexpr ではなかった constexprではありませんでした。

[編集] 関連項目

optional オブジェクトを作成する
(function template) [編集]
English 日本語 中文(简体) 中文(繁體)