- any[meta header]
- std[meta namespace]
- class[meta id-type]
- cpp17[meta cpp]
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");
- std::any_cast[link any_cast.md]
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
を使用するという選択肢がありうる
名前 |
説明 |
対応バージョン |
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 |
名前 |
説明 |
対応バージョン |
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;
}
}
- std::any[color ff0000]
- std::any_cast[link any_cast.md]
- std::bad_any_cast[link bad_any_cast.md]