Frage

Ich möchte eine Karte haben, die eine homogene Schlüsselart aber heterogene Datentypen hat.

Ich möchte in der Lage sein, etwas zu tun wie (Pseudo-Code):

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!

Ich könnte einen Zeiger auf eine Basisklasse als Datentyp haben, aber lieber nicht.

ich nie Schub verwendet haben, bevor aber noch an der Fusionsbibliothek gesucht, aber kann nicht herausfinden, was ich tun muss.

Danke für Ihre Hilfe.

War es hilfreich?

Lösung

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

}

Andere Tipps

: Wie kann ich einen von Objekten unterschiedlicher Typen

  

Sie können nicht, aber Sie können gefälschte es ziemlich gut. In C / C ++ alle Arrays sind homogen (d.h. die Elemente sind alle vom gleichen Typ). Jedoch mit einer zusätzlichen Schicht aus indirection können Sie das Aussehen eines heterogenen Behälters geben (ein heterogener Behälter ist ein Behälter, in dem die enthaltenen Objekte unterschiedlicher Typen sind).

     

Es gibt zwei Fälle mit heterogenen Containern.

     

Der erste Fall tritt auf, wenn alle Objekte, die Sie in einem Behälter gespeichert werden sollen von einer gemeinsamen Basisklasse öffentlich abgeleitet werden. [...]

     

Der zweite Fall tritt auf, wenn die Objekttypen disjunkt sind -. Sie keine gemeinsame Basisklasse teilen
  Der Ansatz hier ist eine Handle-Klasse zu verwenden. Der Behälter ist ein Behälter mit Griff Objekten (nach Wert oder Zeiger, Ihre Wahl, nach Wert ist einfacher). Jeder Griff Objekt weiß, wie man „halten, um“ eines der Objekte (das heißt, einen Zeiger halten) Sie in den Behälter setzen wollen. Sie können entweder eine einzelne Handgriff-Klasse mit mehreren verschiedenen Arten von Zeigern als Instanzdaten oder eine Hierarchie von Handle-Klassen verwenden, die die verschiedenen Typen, die Sie enthalten wollen Schatten (der Behälter der Griffbasisklasse Zeiger sein erfordert). Der Nachteil dieses Ansatzes ist, dass er den Griff Klasse (n) zur Wartung eröffnet jedes Mal, wenn die Menge der zu ändern, die enthalten sein können. Der Vorteil ist, dass Sie den Griff Klasse verwenden kann (es) die meisten der Hässlichkeit der Speicherverwaltung und Objektlebensdauer zu verkapseln. So handle Objekte mit im ersten Fall sogar von Vorteil sein kann.

:: alle tun der Trick für Sie?

Danke David, das war, was ich brauchte. Hier ist die Arbeitslösung.

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

Wenn Sie eine begrenzte Anzahl von Typen wollen unterstützt werden, Boost.Variant sollte es tun.

steigert jeder sicher funktioniert, aber ich denke, mit Int-Technologie zu geben, wie die Taste Art der Fusion Karte eine bessere Lösung ist. Kein Typ Löschung und möglicherweise schneller

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top