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

履歴 編集

class
<any>

std::any(C++17)

namespace std {
  class any;
}

概要

anyクラスは、コピー可能なあらゆる型の値を保持できる記憶域型である。保持する値と型は動的に切り替えることができる。

std::any x = 3; // int型の値3で初期化
x = std::string("Hello"); // std::string型の値"Hello"を再代入

// 値を取り出す
std::string s = std::any_cast<std::string>(x);
assert(s == "Hello");

anyクラスは、古くからあったvoid*をより便利にし、オブジェクトの寿命管理と実行時型情報の機能が付加された型であると言える。

このクラスと同様のことは、たとえばstd::shared_ptr<void>でも行えるが、その場合はポインタの意味論で値を保持することになり、anyの場合は値の意味論で値を保持することになる。また、std::variantクラスも似たようなことができるが、その違いは、variantが代入されうる型の候補が静的に既知であることに対し、anyはその候補を実行時まで遅らせることができるということである。同じことを実現するためにどの設計を採用するかはプログラマに委ねられる。

使用例:

  • イベントハンドラに渡されるパラメータの型として使用する
    • list<function<void(any)>>のようなイベントのリストを保持しておき、たとえば0番目のイベントハンドラにはマウスクリック、1番目のイベントハンドラにはボタンクリックに使用すると想定する
    • マウスクリックにはイベントの引数としてクリックした位置情報 (xとy) が渡され、ボタンクリックにはイベントの引数としてボタンのIDが渡される、というような、イベントの種類ごとに引数の型が異なるという状況がでてくる
    • イベントの種類ごとに異なるイベント変数 (function<void(Point)>function<void(ButtonID)>) を用意するかまとめて扱うかで設計選択があるが、そこでanyを使用するという選択肢がありうる

要件

  • 代入する型はコピー構築可能であること

備考

  • 実装は、小さなオブジェクトを保持するためには動的メモリ確保を回避するべきである。そのようなsmall-object optimizationは、代入される型Tstd::is_nothrow_move_constructible_v<T> == trueの場合にのみ適用されること

メンバ関数

構築・破棄

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

代入

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

値の観測

名前 説明 対応バージョン
has_value 有効な値を保持しているかを判定する C++17
type 保持している値の型情報を取得する C++17

非メンバ関数

ヘルパ関数

名前 説明 対応バージョン
make_any anyオブジェクトを構築する C++17

値の取り出し

名前 説明 対応バージョン
any_cast 値を取り出す C++17

値の入れ替え

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

#include <iostream>
#include <any>

int main()
{
  // int型の値を代入して取り出す
  std::any x = 3;
  int n = std::any_cast<int>(x);

  std::cout << n << std::endl;

  // 文字列を再代入して取り出す
  x = "Hello";
  const char* s = std::any_cast<const char*>(x);

  std::cout << s << std::endl;

  // 間違った型で取り出そうとすると例外が送出される
  try {
    std::any_cast<double>(x);
  }
  catch (std::bad_any_cast& e) {
    std::cout << e.what() << std::endl;
  }
}

出力例

3
Hello
bad any_cast

バージョン

言語

  • C++17

処理系

参照