Question

Je souhaite une carte comportant un type de clé homogène mais des types de données hétérogènes.

Je veux pouvoir faire quelque chose comme (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!

Je pourrais avoir un pointeur sur une classe de base comme type de données mais je ne le ferais pas plutôt.

Je n’ai jamais utilisé boost auparavant, mais j’ai jeté un œil à la bibliothèque de fusion, mais j’ignore ce que je dois faire.

Merci de votre aide.

Était-ce utile?

La solution

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

}

Autres conseils

Comment puis-je créer un < conteneur favori > ; d'objets de différents types?

  

Vous ne pouvez pas, mais vous pouvez très bien faire semblant. En C / C ++, tous les tableaux sont homogènes (c’est-à-dire que les éléments sont tous du même type). Cependant, avec une couche supplémentaire d'indirection, vous pouvez donner l'apparence d'un conteneur hétérogène (un conteneur hétérogène est un conteneur dans lequel les objets contenus sont de types différents).

     

Il existe deux cas avec des conteneurs hétérogènes.

     

Le premier cas se produit lorsque tous les objets que vous souhaitez stocker dans un conteneur sont publiquement dérivés d'une classe de base commune. [...]

     

Le deuxième cas se produit lorsque les types d'objet sont disjoints & # 8212; ils ne partagent pas une classe de base commune.
  L'approche consiste ici à utiliser une classe de descripteurs. Le conteneur est un conteneur d'objets handle (par valeur ou par pointeur, votre choix; par valeur, c'est plus facile). Chaque objet handle sait comment & "Conserver" & "; (c'est-à-dire, maintenez un pointeur sur) l'un des objets que vous souhaitez placer dans le conteneur. Vous pouvez utiliser une classe de descripteurs unique avec plusieurs types de pointeurs différents en tant que données d'instance ou une hiérarchie de classes de descripteurs qui occultent les différents types que vous souhaitez contenir (le conteneur doit contenir des pointeurs de classes de contrôle de base). L'inconvénient de cette approche est qu'elle ouvre la ou les classes de descripteurs à la maintenance chaque fois que vous modifiez l'ensemble des types pouvant être contenus. L'avantage est que vous pouvez utiliser la ou les classes de descripteurs pour encapsuler l'essentiel de la laideur de la gestion de la mémoire et de la durée de vie des objets. Ainsi, l’utilisation d’objets poignée peut être bénéfique même dans le premier cas.

boost :: any do le truc pour vous?

Merci David, c’était ce dont j'avais besoin. Voici la solution de travail.

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

Si vous souhaitez prendre en charge un nombre limité de types, Boost.Variant devrait faire l'affaire.

boost any fonctionne sûrement, mais je pense qu'utiliser Int pour taper Technologie comme type de carte de fusion clé est une meilleure solution. Aucun type d'effacement et peut-être plus rapide

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top