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

履歴 編集

class template
<optional>

std::optional(C++17)

namespace std {
  template <class T>
  class optional;
}

概要

optionalクラスは、任意の型Tの値を有効値として、あらゆる型に共通の無効値状態を表現できる型である。

このクラスには、大きく2つの用途がある:

  1. オブジェクトの初期化タイミングを遅延させる
  2. エラー報告のために、あらゆる型に共通の無効値表現を持たせる

オブジェクトは定義した時点で初期化が行われるが、optionalクラスはその初期化タイミングを遅延させるために使用できる。この用途には、std::shared_ptrのようなスマートポインタを使用することもできるが、このクラスは動的メモリ確保を行わないため、リソース管理ではなく初期化タイミングを遅延させるだけであれば、このクラスの方が適している。

エラー報告について、このクラスを使用しない場合、従来の方法として有効値と無効値は、以下のように表現されていた:

  • int型の場合、0以上の値を有効な値とし、エラーが起きたら負数を代入する
  • ポインタの場合、オブジェクトへのポインタを有効な値とし、どこも指さないヌルポインタを無効値として代入する

このような有効値と無効値の表現は、変数単位もしくはAPI・ライブラリ単位での仕様である。optionalクラスでは、nulloptという特殊な定数を無効値とし、あらゆる型に共通の無効状態を持たせられるようになっている。

このクラスは、ヒープからの動的メモリ確保を行わない。実装は配置newやstd::aligned_storageのような機能によって、スタック領域のメモリのみを使用する。

要件

Tが以下のいずれかに該当してはならない:

また、型T破棄可能であること。

備考

このクラスの前身となったBoost Optional Libraryでは、optional<int&>のように左辺値参照を要素型とした場合に、無効値の領域を最適化する機能が入っていた。

標準ライブラリのoptionalクラスには現在、参照を持たせることはできない。

メンバ関数

構築・破棄

名前 説明 対応バージョン
(constructor) コンストラクタ C++17
(destructor) デストラクタ C++17

代入

名前 説明 対応バージョン
operator= 代入演算子 C++17
emplace 要素型のコンストラクタ引数から直接構築する C++17
swap 他のoptionalオブジェクトとデータを入れ替える C++17
reset 有効値を保持していない状態にする C++17

値の観測

名前 説明 対応バージョン
operator* 間接参照 C++17
operator-> メンバアクセス C++17
operator bool 有効な値を保持しているかを判定する C++17
has_value 有効な値を保持しているかを判定する C++17
value 有効値を取得する C++17
value_or 有効値もしくは指定された無効値を取得する C++17

メンバ型

名前 説明 対応バージョン
value_type 要素型T C++17

非メンバ関数

ヘルパ関数

名前 説明 対応バージョン
make_optional 有効な値を保持するoptionalオブジェクトを構築する C++17

値の入れ替え

名前 説明 対応バージョン
swap 2つのoptionalオブジェクトを入れ替える C++17

比較演算子

名前 説明 対応バージョン
operator== 等値比較 C++17
operator!= 非等値比較 C++17
operator< 左辺が右辺より小さいかを判定する C++17
operator<= 左辺が右辺以下かを判定する C++17
operator> 左辺が右辺より大きいかを判定する C++17
operator>= 左辺が右辺以上かを判定する C++17

推論補助

名前 説明 対応バージョン
(deduction_guide) クラステンプレートの推論補助 C++17

ハッシュサポート

名前 説明 対応バージョン
template <class T> struct hash; hashクラスの先行宣言 C++17
template <class T> struct hash<optional<T>>; hashクラスのoptionalに対する特殊化 C++17

#include <iostream>
#include <optional>

// 除算をする関数。
// ゼロ割りを試みた場合、無効値が返る
std::optional<int> safe_divide(int a, int b)
{
  if (b == 0)
    return std::nullopt;

  return a / b;
}

int main()
{
  // 9/3を計算する
  std::optional<int> result1 = safe_divide(9, 3);
  if (result1) { // 計算に成功した場合、有効値が返る
    int x = result1.value(); // 有効値を取り出す
    std::cout << x << std::endl;
  }

  // 3/0の計算を試みる
  std::optional<int> result2 = safe_divide(3, 0);
  if (!result2) { // 計算に失敗した場合、無効値が返る
    std::cout << "error" << std::endl;
  }
}

出力

3
error

バージョン

言語

  • C++17

処理系

参照