Namespaces
Variants

std::any:: type

From cppreference.net
Utilities library
const std:: type_info & type ( ) const noexcept ;
(C++17以降)

含まれる型をクエリします。

戻り値

インスタンスが非空の場合に含まれる値の typeid 、そうでない場合は typeid ( void )

この例は、コンパイル時および実行時に新しいビジターを登録する機能を備えた std::any ビジターイディオムを示しています。

#include <any>
#include <functional>
#include <iomanip>
#include <iostream>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <vector>
template<class T, class F>
inline std::pair<const std::type_index, std::function<void(const std::any&)>>
    to_any_visitor(const F& f)
{
    return
    {
        std::type_index(typeid(T)),
        [g = f](std::any const& a)
        {
            if constexpr (std::is_void_v<T>)
                g();
            else
                g(std::any_cast<T const&>(a));
        }
    };
}
static std::unordered_map<std::type_index, std::function<void(const std::any&)>>
    any_visitor
{
    to_any_visitor<void>([]
(注:元のテキストは閉じ括弧のみのため、日本語でも同じ記号を保持します) { std::cout << "{}"; }),
    to_any_visitor<int>([](int x) { std::cout << x; }),
    to_any_visitor<unsigned>([](unsigned x) { std::cout << x; }),
    to_any_visitor<float>([](float x) { std::cout << x; }),
    to_any_visitor<double>([](double x) { std::cout << x; }),
    to_any_visitor<char const*>([](char const* s)
        { std::cout << std::quoted
(注:指示に従い、HTMLタグ・属性は翻訳せず、C++固有用語も翻訳していません。表示されるテキスト「std::quoted」はC++標準ライブラリの関数名であるため、そのまま保持しています)(s); }),
    // ... あなたの型に対するハンドラをさらに追加 ...
};
inline void process(const std::any& a)
{
    if (const auto it = any_visitor.find(std::type_index(a.type()));
        it != any_visitor.cend())
        it->second(a);
    else
        std::cout << "未登録の型 " << std::quoted
(注:指示に従い、HTMLタグ・属性は翻訳せず、C++固有用語も翻訳していません。表示されるテキスト「std::quoted」はC++標準ライブラリの関数名であるため、そのまま保持しています)(a.type().name());
}
template<class T, class F>
inline void register_any_visitor(const F& f)
{
    std::cout << "型のビジターを登録"
              << std::quoted
(注:指示に従い、HTMLタグ・属性は翻訳せず、C++固有用語も翻訳していません。表示されるテキスト「std::quoted」はC++標準ライブラリの関数名であるため、そのまま保持しています)(typeid(T).name()) << '\n';
    any_visitor.insert(to_any_visitor<T>(f));
}
int main()
{
    std::vector<std::any> va{{}, 42, 123u, 3.14159f, 2.71828, "C++17"};
    for (int n{}; const std::any& a : va)
    {
        std::cout << (n++ ? ", " : "[");
        process(a);
    }
    std::cout << "]\n";
    process(std::any(0xFULL)); //< 未登録の型 "y" (unsigned long long)
    std::cout << '\n';
    register_any_visitor<unsigned long long>([](auto x)
    {
        std::cout << std::hex << std::showbase << x; 
    });
    process(std::any(0xFULL)); //< OK: 0xf
    std::cout << '\n';
}

出力例:

[{}, 42, 123, 3.14159, 2.71828, "C++17"]
未登録の型 "y"
型 "y" のビジターを登録
0xf

関連項目

(C++11)
type_info オブジェクトのラッパーで、連想コンテナおよび非順序連想コンテナのインデックスとして使用可能
(クラス)