32

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

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

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!

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

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

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

4

6 に答える 6

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

}
于 2008-10-30T23:12:08.610 に答える
10

さまざまなタイプのオブジェクトの <favorite container> を構築するにはどうすればよいですか?

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

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

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

2 番目のケースは、オブジェクト タイプがばらばらである場合に発生します。つまり、共通の基底クラスを共有していません。
ここでのアプローチは、ハンドル クラスを使用することです。コンテナーは、ハンドル オブジェクトのコンテナーです (値によるかポインターによるかを選択できます。値による方が簡単です)。各ハンドル オブジェクトは、コンテナーに配置するオブジェクトの 1 つを "保持" (つまり、ポインターを保持) する方法を認識しています。インスタンス データとしていくつかの異なる型のポインターを持つ単一のハンドル クラスを使用するか、格納するさまざまな型をシャドウするハンドル クラスの階層を使用できます (コンテナーがハンドル基本クラス ポインターである必要があります)。このアプローチの欠点は、含めることができる型のセットを変更するたびに、ハンドル クラスをメンテナンスに開放することです。利点は、ハンドル クラスを使用して、メモリ管理とオブジェクトの有効期間の醜さのほとんどをカプセル化できることです。

于 2008-10-30T19:28:40.247 に答える
8

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

于 2008-10-30T19:28:48.607 に答える
7

ありがとうデビッド、それが私が必要としていたものでした。これが実用的なソリューションです。

#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;
}
于 2008-10-31T00:04:10.533 に答える
5

限定されたタイプのセットをサポートする必要がある場合は、Boost.Variantを使用する必要があります。

于 2008-10-30T20:22:43.553 に答える
0

boost any は確かに機能しますが、フュージョン マップのキー タイプとして Int を使用して Technology をタイプする方が良い解決策だと思います。型消去がなく、おそらく高速

于 2017-05-14T14:00:23.860 に答える