web-dev-qa-db-ja.com

異種のboost :: mapをどのように作成しますか?

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

(擬似コード)のようなことができるようになりたい:

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!

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

私はこれまでブーストを使用したことがありませんが、フュージョンライブラリを調べましたが、何をする必要があるのか​​理解できません。

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

31
Kurt
#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";
    }

}
38
Martin York

異なるタイプのオブジェクトの<お気に入りのコンテナ>を構築するにはどうすればよいですか?

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

異種コンテナの場合は2つあります。

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

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

10
Leon Timmermans

boost :: any あなたのためにトリックをしますか?

8
activout.se

デビッドありがとう、それが私が必要としていたものでした。これが実用的な解決策です。

#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;
}
6
Kurt

限定されたタイプのセットをサポートしたい場合は、 Boost.Variant でうまくいくはずです。

5
Ferruccio

ブーストは確かに機能しますが、融合マップの主要なタイプとしてIntを使用してテクノロジーを入力する方が良い解決策だと思います。型消去なしで、おそらくより高速

0
FaceBro