J'ai juste besoin d'un dictionnaire ou d'un tableau associatif string
=> int
.
Il existe une carte de type C ++ pour ce cas.
Mais je n'ai besoin que d'une seule carte pour toutes les instances (-> statique) et cette carte ne peut pas être modifiée (-> const);
J'ai trouvé ce moyen avec la bibliothèque boost
std::map<int, char> example =
boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
Existe-t-il une autre solution sans cette bibliothèque? J'ai essayé quelque chose comme ça, mais il y a toujours des problèmes avec l'initialisation de la carte.
class myClass{
private:
static map<int,int> create_map()
{
map<int,int> m;
m[1] = 2;
m[3] = 4;
m[5] = 6;
return m;
}
static map<int,int> myMap = create_map();
};
v = k + 'a' - 1
.Réponses:
la source
Boost.Assign
design similaire est assez chouette aussi :)cout << A::myMap[1];
dansmain()
. Cela donne une erreur. L'erreur ne se produit pas si je supprime lesconst
qualificatifs, donc je suppose que les cartes neoperator[]
peuvent pas gérer unconst map
, au moins, pas dans l'implémentation g ++ de la bibliothèque C ++.const_map.cpp:22:23: error: passing ‘const std::map<int, int>’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’ discards qualifiers [-fpermissive]
La norme C ++ 11 a introduit l'initialisation uniforme, ce qui rend cela beaucoup plus simple si votre compilateur la prend en charge:
Voir aussi cette section de Professional C ++ , sur unordered_maps.
la source
Je l'ai fait! :)
Fonctionne bien sans C ++ 11
la source
Si vous trouvez
boost::assign::map_list_of
utile, mais que vous ne pouvez pas l'utiliser pour une raison quelconque, vous pouvez écrire le vôtre :Il est utile de savoir comment de telles choses fonctionnent, surtout quand elles sont si courtes, mais dans ce cas, j'utiliserais une fonction:
a.hpp
a.cpp
la source
Une approche différente du problème:
C'est plus efficace, car il n'y a pas de copie de type unique d'une pile à l'autre (y compris le constructeur, les destructeurs sur tous les éléments). Que cela compte ou non dépend de votre cas d'utilisation. Peu importe avec les cordes! (mais vous pouvez ou non trouver cette version "plus propre")
la source
Si la mappe ne doit contenir que des entrées connues au moment de la compilation et que les clés de la mappe sont des entiers, vous n'avez pas du tout besoin d'utiliser une mappe.
la source
switch
horrible, cependant. Pourquoi pasreturn key + 'a' - 1
?return key + 'a' - 1
cela ne fonctionnerait pas pour sa cartographie réelle.Vous pouvez essayer ceci:
MyClass.h
MaClasse.cpp
Avec cette implémentation, votre carte statique constante de classes est un membre privé et peut être accessible à d'autres classes à l'aide d'une méthode get publique. Sinon, comme elle est constante et ne peut pas changer, vous pouvez supprimer la méthode publique get et déplacer la variable map dans la section publique des classes. Je laisserais cependant la méthode createMap privée ou protégée si l'héritage et / ou le polymorphisme est requis. Voici quelques exemples d'utilisation.
J'avais édité mon message original, il n'y avait rien de mal avec le code original dans lequel j'ai posté pour cela compilé, construit et exécuté correctement, c'est juste que ma première version que j'ai présentée comme réponse, la carte a été déclarée comme publique et la carte était const mais n'était pas statique.
la source
Si vous utilisez un compilateur qui ne prend toujours pas en charge l'initialisation universelle ou si vous avez une réservation dans l'utilisation de Boost, une autre alternative possible serait la suivante
la source
Un appel de fonction ne peut pas apparaître dans une expression constante.
essayez ceci: (juste un exemple)
la source
static map<int,int> myMap = create_map();
est incorrect.struct testdata { testdata(int){} }; struct test { static const testdata td = 5; }; testdata test::td;
compilation échouera même si l'initialisation est effectuée avec une expression constante (5
). Autrement dit, «l'expression constante» n'est pas pertinente pour l'exactitude (ou l'absence de celle-ci) du code initial.J'utilise souvent ce modèle et je vous recommande de l'utiliser également:
Bien sûr, ce n'est pas très lisible, mais sans autres bibliothèques, c'est mieux que nous puissions faire. De plus, il n'y aura pas d'opérations redondantes comme la copie d'une carte à une autre comme dans votre tentative.
C'est encore plus utile à l'intérieur des fonctions: au lieu de:
Utilisez le suivant:
Non seulement vous n'avez plus besoin ici de traiter la variable booléenne, mais vous n'aurez plus de variable globale cachée qui est vérifiée si l'initialiseur de la variable statique à l'intérieur de la fonction a déjà été appelé.
la source