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

履歴 編集

function template
<variant>

std::get(C++17)

namespace std {
  template <size_t I, class... Types>
  constexpr variant_alternative_t<I, variant<Types...>>&
    get(variant<Types...>& v);                                   // (1)

  template <size_t I, class... Types>
  constexpr variant_alternative_t<I, variant<Types...>>&&
    get(variant<Types...>&& v);                                  // (2)

  template <size_t I, class... Types>
  constexpr const variant_alternative_t<I, variant<Types...>>&
    get(const variant<Types...>& v);                             // (3)

  template <size_t I, class... Types>
  constexpr const variant_alternative_t<I, variant<Types...>>&&
    get(const variant<Types...>&& v);                            // (4)

  template <class T, class... Types>
  constexpr T& get(variant<Types...>& v);                        // (5)

  template <class T, class... Types>
  constexpr T&& get(variant<Types...>&& v);                      // (6)

  template <class T, class... Types>
  constexpr const T& get(const variant<Types...>& v);            // (7)

  template <class T, class... Types>
  constexpr const T&& get(const variant<Types...>&& v);          // (8)
}

概要

variantオブジェクトから、指定したインデックスもしくは型の値を取得する。

  • (1) : 非const左辺値のvariantオブジェクトから、候補型のインデックスを指定して値を取得する
  • (2) : 非const右辺値のvariantオブジェクトから、候補型のインデックスを指定して値を取得する
  • (3) : const左辺値のvariantオブジェクトから、候補型のインデックスを指定して値を取得する
  • (4) : const右辺値のvariantオブジェクトから、候補型のインデックスを指定して値を取得する
  • (5) : 非const左辺値のvariantオブジェクトから、候補型を指定して値を取得する
  • (6) : 非const右辺値のvariantオブジェクトから、候補型を指定して値を取得する
  • (7) : const左辺値のvariantオブジェクトから、候補型を指定して値を取得する
  • (8) : const右辺値のvariantオブジェクトから、候補型を指定して値を取得する

要件

  • (1), (2), (3), (4) : I < sizeof...(Types)であること。そうでなければプログラムは不適格となる
  • (5), (6), (7), (8) : Types...内に型Tが正確にひとつ含まれること。そうでなければプログラムは不適格となる

戻り値

  • (1), (2), (3), (4) : v.index()Iが等値である場合、variantオブジェクトに保持されているI番目の候補型の値を返す。そうでなければ、std::bad_variant_access例外を送出する
  • (5), (6), (7), (8) : vT型の値を保持している場合、その値への参照を返す。そうでなければ、std::bad_variant_access例外を送出する

例外

  • (1), (2), (3), (4) : 指定したインデックスの型がvオブジェクトに保持されていない場合、std::bad_variant_access例外を送出する
  • (5), (6), (7), (8) : 指定した型がvオブジェクトに保持されていない場合、std::bad_variant_access例外を送出する

例外を投げる動作が好ましくない場合はget_if()を使用する。こちらの関数は例外を投げる代わりにnullptrを返す。

備考

  • この関数がメンバ関数ではなく非メンバ関数として定義されているのは、ユーザーにtemplate限定子を指定させるのを避けるためである。メンバ関数にした場合、テンプレート内でその関数を使用すると、v.template get<I>()のようにtemplateキーワードをユーザーが指定しなければならない
  • 同名の非メンバ関数get()がタプルインタフェースとして定義されているが、この関数はタプルインタフェースではない

#include <iostream>
#include <variant>
#include <string>

std::variant<int, char, std::string> make()
{
  return std::string{"hello"};
}

const std::variant<int, char, std::string> const_make()
{
  return std::string{"hello"};
}

int main()
{
  // (1)
  {
    std::variant<int, char, std::string> v = 3;

    // 保持している値の型はintなので、
    // 0番目 (int, char, stringの先頭インデックス) を指定して値を取り出す
    int& x = std::get<0>(v);
    std::cout << "(1) : " << x << std::endl;
  }

  // (2)
  {
    // variantの一時オブジェクトから、
    // 型のインデックスを指定して値を取り出す
    std::string x = std::get<2>(make());

    std::cout << "(2) : " << x << std::endl;
  }

  // (3)
  {
    const std::variant<int, char, std::string> v = 'a';

    // const左辺値参照のvariantオブジェクトを渡すと、
    // const左辺値参照の値が返る
    const char& x = std::get<1>(v);
    std::cout << "(3) : " << x << std::endl;
  }

  // (4)
  {
    // const付きのvariant一時オブジェクトを渡すと、
    // const右辺値参照の値が返る
    const std::string x = std::get<2>(const_make());

    std::cout << "(4) : " << x << std::endl;
  }

  // (5)
  {
    std::variant<int, char, std::string> v = 3;

    // 保持している型を指定して値を取り出す。
    int& x = std::get<int>(v);
    std::cout << "(5) : " << x << std::endl;

    // 以下のコードはコンパイルエラーになる。
    // variantのクラステンプレート引数に与えた型を、ここでは指定しなければならない
    // const int& y = std::get<const int>(v);
  }

  // (6)
  {
    // variantの一時オブジェクトから、
    // 型を指定して値を取り出す
    std::string x = std::get<std::string>(make());

    std::cout << "(6) : " << x << std::endl;
  }

  // (7)
  {
    const std::variant<int, char, std::string> v = 'a';

    // const左辺値参照のvariantオブジェクトを渡すと、
    // const左辺値参照の値が返る
    const char& x = std::get<char>(v);
    std::cout << "(7) : " << x << std::endl;
  }

  // (8)
  {
    // const付きのvariant一時オブジェクトを渡すと、
    // const右辺値参照の値が返る
    const std::string x = std::get<std::string>(const_make());

    std::cout << "(8) : " << x << std::endl;
  }
}

出力

(1) : 3
(2) : hello
(3) : a
(4) : hello
(5) : 3
(6) : hello
(7) : a
(8) : hello

get関数をADLで呼び出す (C++20)

#include <iostream>
#include <variant>

int main() {
  std::variant<int, char> v = 1;
  std::cout << get<int>(v) << std::endl; // C++17:NG C++20:OK
}

出力

1

バージョン

言語

  • C++17

処理系

関連項目