最終更新日時:
が更新

履歴 編集

動的型

Boost.Any

インデックス

あらゆる型の値を代入する

boost::any型には、あらゆる型の値を格納することができる。

格納されている型のチェックには、boost::any::type()メンバ関数を使用し、std::type_info型で判定することができる。

格納されている値を元の型に変換するには、boost::any_cast()関数を使用する。

#include <iostream>
#include <string>
#include <boost/any.hpp>

int main()
{
    boost::any x = 1; // int値を格納
    x = std::string("Hello"); // std::string値を格納

    // 格納されている型をチェック
    if (x.type() == typeid(std::string)) {
        // 元の型に変換
        std::cout << boost::any_cast<std::string>(x) << std::endl;
    }
    else {
        std::cout << "not string" << std::endl;
    }
}

実行結果:

Hello

値を取り出す

boost::anyに代入した値を取り出すには、boost::any_cast()関数を使用する。

この関数の使用方法は、コピーして取り出す、値を参照する、値へのポインタを取得する、の3つがある。

方法1. 値をコピーして取り出す。

boost::any a;

T x = boost::any_cast<T>(a);

この例のように、テンプレート引数に取り出す型Tを指定し、引数としてboost::anyオブジェクトへの参照を渡すことで、boost::any型に格納されている型Tのオブジェクトを、コピーで取り出すことができる。

Tのオブジェクトが格納されていない場合には、boost::bad_any_cast例外が投げられる。

方法2. 値を参照する。

boost::any a;

T& x = boost::any_cast<T&>(a);

この例のように、テンプレート引数にT&を指定した場合、boost::any型に格納されている型Tのオブジェクトを参照することができる。

Tのオブジェクトが格納されていない場合には、boost::bad_any_cast例外が投げられる。

方法3. 値へのポインタを取得する。

boost::any a;
T* x = boost::any_cast<T>(&a);

この例のように、テンプレート引数に型Tを指定し、引数としてboost::anyオブジェクトへのポインタを渡すことで、boost::any型に格納されている型Tのオブジェクトへのポインタを取得できる。

Tのオブジェクトが格納されていない場合には、ヌルポインタが返される。

あらゆる型の値をコンテナに入れる

std::vector<boost::any>のようにすれば、あらゆる型の値をコンテナに入れることができる。

このようなコンテナは、ヘテロなコンテナ(heterogeneous containers)と呼ばれる。

#include <iostream>
#include <string>
#include <vector>
#include <boost/any.hpp>
#include <boost/foreach.hpp>

int main()
{
    std::vector<boost::any> v;
    v.push_back(1);
    v.push_back(std::string("Hello"));
    v.push_back(3.14);

    BOOST_FOREACH (const boost::any& x, v) {
        if (x.type() == typeid(int)) {
            std::cout << "int : " << boost::any_cast<int>(x) << std::endl;
        }
        else if (x.type() == typeid(std::string)) {
            std::cout << "string : " << boost::any_cast<std::string>(x) << std::endl;
        }
        else if (x.type() == typeid(double)) {
            std::cout << "double : " << boost::any_cast<double>(x) << std::endl;
        }
        else {
            std::cout << "unknown type" << std::endl;
        }
    }
}

実行結果:

int : 1
string : Hello
double : 3.14