質問

同種のキータイプで、異種のデータタイプを持つマップが必要です。

(擬似コード)のようなことをしたい:

boost::map<std::string, magic_goes_here> m;
m.add<int>("a", 2);
m.add<std::string>("b", "black sheep");

int i = m.get<int>("a");
int j = m.get<int>("b"); // error!

データ型として基本クラスへのポインタを使用できますが、そうではありません。

これまでにboostを使用したことはありませんが、フュージョンライブラリを調べましたが、何をする必要があるかわかりません。

ご協力ありがとうございます。

役に立ちましたか?

解決

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

int main()
{
    try
    {
        std::map<std::string, boost::any> m;
        m["a"]  = 2;
        m["b"]  = static_cast<char const *>("black sheep");

        int i = boost::any_cast<int>(m["a"]);
        std::cout << "I(" << i << ")\n";

        int j = boost::any_cast<int>(m["b"]); // throws exception
        std::cout << "J(" << j << ")\n";
    }
    catch(...)
    {
        std::cout << "Exception\n";
    }

}

他のヒント

<!> lt; favorite container <!> gtを構築する方法;種類の異なるオブジェクトの場合

  

できませんが、かなり上手に偽造できます。 C / C ++では、すべての配列は同種です(つまり、要素はすべて同じ型です)。ただし、インダイレクションの追加レイヤーを使用すると、異種コンテナーの外観を与えることができます(異種コンテナーとは、含まれるオブジェクトのタイプが異なるコンテナーです)。

     

異種コンテナには2つのケースがあります。

     

最初のケースは、コンテナに保存するすべてのオブジェクトが共通の基本クラスからパブリックに派生した場合に発生します。 [...]

     

2番目のケースは、オブジェクトタイプが互いに素である場合に発生します<!>#8212;共通の基本クラスは共有しません。
  ここでのアプローチは、ハンドルクラスを使用することです。コンテナーは、ハンドルオブジェクトのコンテナーです(値またはポインターによる選択、値による方が簡単です)。各ハンドルオブジェクトは、<!> quot;を保持する方法を知っています; <!> quot; (つまり、ポインタを維持する)コンテナに入れたいオブジェクトの1つ。インスタンスデータとして、いくつかの異なるタイプのポインターを持つ単一のハンドルクラスを使用するか、さまざまなタイプを格納するハンドルクラスの階層を使用できます(コンテナーはハンドルベースクラスポインターである必要があります)。このアプローチの欠点は、格納できるタイプのセットを変更するたびに、ハンドルクラスをメンテナンス用に開くことです。利点は、ハンドルクラスを使用して、メモリ管理とオブジェクトライフタイムのさのほとんどをカプセル化できることです。したがって、最初の場合でも、ハンドルオブジェクトを使用すると有益な場合があります。

boost :: any あなたのためのトリック?

デビッド、ありがとう。これが実用的なソリューションです。

#include <iostream>
using std::cout;
using std::endl;

#include <map>
#include <boost/any.hpp>

using boost::any_cast;
typedef std::map<std::string, boost::any> t_map;


int main(int argc, char **argv)
{

  t_map map;
  char *pc = "boo yeah!";

  map["a"] = 2.1;
  map["b"] = pc;

  cout << "map contents" << endl;
  cout << any_cast<double>(map["a"]) << endl;
  cout << any_cast<char*>(map["b"]) << endl;

  return 0;
}

限られたタイプのセットをサポートしたい場合、 Boost.Variant がトリックを行う必要があります。

boostは確かに機能しますが、Intを使用してFusionマップの主要なタイプとしてTechnologyを入力する方がより良いソリューションだと思います。型の消去はなく、おそらくより高速です

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top