Comment puis-je stocker des objets de types différents dans un C++ conteneur?
Est-il C++ conteneur que je pourrais utiliser ou de construire qui peut contenir, disons, int
et string
et double
types? Le problème que je me pose, c'est que chaque fois que j'essaie de remplir, de dire, d'une carte, d'un vecteur ou d'une liste, par exemple, les suivantes:
int x;
string y;
double z;
Je suis limité par le format:
list<int> mycountainer;
vector<string> mycontainer;
qui forces mycontainer
à seulement constitués d'un seul type.
Avant tout le suggèrent les génériques, qui ne fonctionne pas, soit depuis la norme vector
et list
les contenants qui viennent avec le C++ sont déjà des génériques - ils peuvent être conteneur pour tous les types, mais ne peut pas contenir plusieurs types.
Je voudrais éviter d'utiliser Boost aussi, si possible, je préfère si il existe un moyen simple je ne pouvais le code moi-même.
[modifier]
Hey les gars, merci beaucoup pour vos suggestions, je dois expliquer comment je vais utiliser ce conteneur, mais c'est un peu compliqué, d'où le (gros) simplification ci-dessus. Je pense que la meilleure option ici est d'utiliser le Boost. Merci encore.
- Euh...
struct
quelqu'un? Ouclass
? - avez-vous essayé d'utiliser
union
? - Dans la norme actuelle (cela va changer avec C++0x) vous ne pouvez pas utiliser
std::string
à l'intérieur de l'union. - Pourquoi voulez-vous faire? Comment comptez-vous sur l'utilisation du conteneur? Comment allez-vous vérifier ce que vous avez inséré?
- Est-ce une sorte de dup de stackoverflow.com/questions/251403/... ?
- La caisse Poco::Aucun ; Source est facile pocoproject.org/docs/Poco.Any.html
Vous devez vous connecter pour publier un commentaire.
Vous pourriez utiliser (ou ré-implémenter)
boost::any
et stocker les instances deboost::any
dans un récipient. Ce serait le plus sûr, depuisboost::any
a probablement reçu beaucoup de cas de bord et de la complexité impliquée dans la résolution de ce genre de problème dans le cas général.Si vous voulez faire quelque chose de rapide et sale, créer une structure ou peut-être une union contenant des membres de tous les types de long avec une énumération ou tout autre indicateur de type "actif" dans l'objet. Soyez particulièrement prudent avec les syndicats parce qu'ils ont des propriétés intéressantes (comme en invoquant un comportement indéfini si vous lisez le mauvais membre de l'union, un seul des membres peut être "active" à la fois, le plus récemment écrites).
Je suis curieux de ce que vous êtes en train de faire que vous avez besoin d'une telle construction, cependant.
boost::any
. Aussi, comme je l'ai déjà indiqué dans le commentaire de @Elalfer, vous ne pouvez pas stockerstd::string
dans une union.std::any
à la place si vous ne voulez pas utiliser de Stimuler et d'avoir accès à C++17 🙂Bien, la première question serait: Pourquoi pensez-vous que vous avez besoin de stocker des objets de différentes, totalement sans rapport avec les types dans le même conteneur? Qui semble louche pour moi.
Si j'en avais le besoin, j'aurais l'air dans
boost::variant
ouboost::any
.boost::variant
etboost::any
est de stocker des objets indépendants. En tant que tel, j'ai utilisé de tels types, mais je doute que cela a été plus d'une fois par décennie. Donc mon conseil à la question de la conception.Ce que vous voulez est appelé un "hetrogenious conteneur". C++ n'est pas techniquement de les soutenir dans la STL, mais le Boost n'.
Donné, je pense que vous trouverez votre réponse à cette question: comment-ne-vous-faire-un-hétérogène-boostmap
Vous pouvez utiliser des structures ou à des classes ou std::pair.
[modifier]
Pour les classes et les structures:
Pour std::pair:
Vous pouvez utiliser une structure qui contient toutes les trois.
Ensuite, vous pouvez simplement déclarer
list mycontainer<Data>
et utiliser la valeur la plus appropriée, à condition de savoir ce que la valeur type est. Si non, ajouter le champ à la structure qui vous indique quels sont les trois types de données est en cours d'utilisation.Si vous êtes inquiet au sujet de l'utilisation de la mémoire, vous pouvez probablement utiliser un syndicat, même si j'ai tendance à éviter de les utiliser. Il peut être inutile de la paranoïa de ma part si.
Si vous avez un nombre fini d'éléments, vous devez les stocker, de les mettre dans une classe ou structure.
Si il n'y a pas de limite pour les éléments que vous avez besoin de stocker dans ce conteneur, puis regarder d'une manière différente de faire les choses parce que la seule façon de le faire est de les stocker comme un objet, et ensuite coulée dans leur propre type lorsque vous avez besoin d'y accéder.
Cependant, si n'importe quel élément pourrait être dans le récipient, vous n'avez aucun moyen de savoir quel est le type des éléments spécifiques dans le conteneur sont, et ne seront donc pas en mesure de les jeter.
Si C++ contenus de réflexion, il serait peut-être une façon de le faire, mais le C++ n'a pas de réflexion.
La méthode la plus simple est de définir une structure ou d'une classe qui a des membres de chacun des types que vous souhaitez stocker. Josh réponse suggère Coup de pouce.Tout, qui se tient assez bien rien. Si vous voulez restreindre valeurs à celles de types
int
,double
, etstd::string
, alors le meilleur choix serait Coup de pouce.Variante.Si vous n'avez simplement pas voulez pour utiliser Boost, alors je vous suggère d'obtenir plus de votre hang-ups et de l'utiliser de toute façon. "Pas Inventé Ici" est une auto-destructeur de la politique. Mais si vous ne peut pas utiliser Boost, alors vous pouvez écrire votre propre variante de la classe à la place. Andrei Alexandrescu a écrit une série en trois parties sur que (partie 1, partie 2, partie 3) il y a quelques années, et son design inspiré de la un coup de pouce utilise.