Le stockage mst carte dans la carte
J'ai pour stocker des std::map comme valeur dans std::map
std::map< std::string, std::map<std::string, std::string> > someStorage;
Comment les insérer dans la deuxième(intérieure) de la carte? J'ai essayé avec:
someStorage.insert( std::make_pair("key", std::make_pair("key2", "value2")) );
Mais cela jette un grand nombre d'erreurs. Quel est le problème?
- Pouvez-vous modifier pour être plus précis que "jette un grand nombre d'erreurs"?
Vous devez vous connecter pour publier un commentaire.
Essayer:
most
std::string implémentations utilise une copie sur écriture approche et donc la chaîne n'est pas fait de copie).char const*
- t-il ? La valeur par défautstd::string
probablement de performance aucune allocation de mémoire (si vôtre, tirer hors de votre bibliothèque fournisseur), et puis il y astd::string& std::string::operator=(char const*)
, et bien sûr, si la chaîne existe déjà, alors vous éviter d'avoir à construire un temporairestd::string
qui ne sera pas inséré de toute façon... I pense que vous êtes d'être inutilement snappy ces jours-ci.insert
qu'il va remplacer une valeur qui est déjà là alors queinsert
ne sera pas. Ce qui est préférable dépend du contexte, bien sûr-mais la question de départ, dans ce cas ne semblent poser pourinsert
.std::map
oustd::unordered_map
.Si vous avez toujours voulu utiliser l'insérer sur la face extérieure de la carte en tant que bien, ici, c'est une façon de le faire
std::map<Key, Value>::value_type
il est typedefed exactement pour cette raison.make_pair
est toujours garanti pour fonctionner ici (et pour ce que ça vaut, c'est les expressions idiomatiques, lorsqu'il fait uninsert
dans mon expérience).make_pair
peut souvent être plus lisible. Si ils vous causer un problème de performances (vous profilés, je suppose), alors bien sûr, c'est juste assez pour l'utiliservalue_type
. Mais sinon, je ne vois pas un avantage majeur. Supposons que votre carte eststd::map<VeryLongKeyTypeName,VeryLongValueTypeName> m;
, vous seriez certainement voulez éviter d'écrirem.insert(std::map<VLKTN,VLVTN>::value_type(k,v));
quand vous pourriez écrirem.insert(std::make_pair(k,v));
-- ce dernier est beaucoup plus clair.typedef
, mais c'est plus embêtant pour ce qui est dans la plupart des cas, peu ou pas d'avantages. Et si votre type de carte dépend des paramètres de modèle, alors vous finissez par avoir à ajouter detypename
avantstd::map<K,V>::value_type
à chaque fois. Vous pourriez fairetypedef typename std::map<K,V>::value_type MapVal;
et puism.insert(MapVal(k,v));
, bien sûr, mais je ne vois pas l'avantage réel.typedef std::map<VeryLongKeyTypeName,VeryLongValueTypeName> Storage;
Puis sonm.insert(Storage::value_type(key,value));
Qui est beaucoup plus propre et plus lisible. Le coût de la conversion implicite n'est pas la question (je suis sûr que les optimisations du compilateur rendrait pratiquement le même). La conversion implicite est problématique, car il n'est pas toujours évident de savoir ce qui se passe (il vous arrive d'avoir de la chance dans le std::string est très bien testé en ce qui concerne, tout autre type défini par l'utilisateur, je serais beaucoup plus méfiant de ce qui se passe (et donc besoin de passer du temps à vérifier)).VeryLongKeyTypeName
est un paramètre du modèle, il finirait par êtretypename Storage::value_type(key, value)
bien sûr, parce quevalue_type
serait encore un type de charge. (Tout en décidant comment répondre pour le reste, l'ours avec moi... :))explicit
sauf si particulier, j'ai été l'intention de permettre la conversion implicite. (J'avais aussi dans l'objectif d'éviter imprudent d'opérateurs de conversion, par exemple l'octroi deoperator const char*
pour un type de chaîne.) Si seulement sensible conversions implicites sont pris en charge, je ne vois pas pourquoi il devrait y avoir un problème majeur.value_type
façon implique potentiellement une inutilestypedef
, et est un peu plus compliqué, mais rend les types impliqués plus explicite. Lemake_pair
est un peu plus pratique. Si utilisé correctement, je ne pense pas que ce soit doit causer de réels problèmes. (J'ai changé les principaux types de cartes avant, et je n'ai jamais eu un problème avec les conversions implicites.) YMMV - je suppose que je n'aurais pas un problème majeur avec l'utilisationvalue_type
si j'ai travaillé dans l'une de vos équipes, mais je ne pense pas qu'il achète vraiment très bien.std::map<Key, Value>::value_type
il est typedefed exactement pour cette raison.make_pair
est toujours garanti pour fonctionner ici (et pour ce que ça vaut, c'est les expressions idiomatiques, lorsqu'il fait uninsert
dans mon expérience).make_pair
peut souvent être plus lisible. Si ils vous causer un problème de performances (vous profilés, je suppose), alors bien sûr, c'est juste assez pour l'utiliservalue_type
. Mais sinon, je ne vois pas un avantage majeur. Supposons que votre carte eststd::map<VeryLongKeyTypeName,VeryLongValueTypeName> m;
, vous seriez certainement voulez éviter d'écrirem.insert(std::map<VLKTN,VLVTN>::value_type(k,v));
quand vous pourriez écrirem.insert(std::make_pair(k,v));
-- ce dernier est beaucoup plus clair.typedef
, mais c'est plus embêtant pour ce qui estUne carte a une méthode d'insertion qui accepte une paire clé/valeur. Votre clé est de type chaîne, ce qui n'est pas un problème, mais votre valeur est pas de type paire (qui vous générez), mais de type de carte. Donc, vous avez besoin de stocker une carte complète comme valeur ou vous modifiez la carte initiale de définition d'accepter une paire comme valeur.
//Essayez ceci:
//Imprimer la carte:
Vous pouvez également utiliser la liste d'initialisation: