Quelle est la bonne façon d'initialiser une carte statique? Avons-nous besoin d'une fonction statique qui l'initialise?
448
En utilisant C ++ 11:
#include <map>
using namespace std;
map<int, char> m = {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};
Utilisation de Boost.Assign :
#include <map>
#include "boost/assign.hpp"
using namespace std;
using namespace boost::assign;
map<int, char> m = map_list_of (1, 'a') (3, 'b') (5, 'c') (7, 'd');
Le meilleur moyen est d'utiliser une fonction:
la source
extern
les variables n'auront pas leurs valeurs correctes dans ce «avant le constructeur principal» si le compilateur n'a vu que laextern
déclaration, mais n'a pas encore exécuté la définition de variable réelle .const map<int,int> m = create_map()
(et ainsi, initialiser les membres const d'une classe dans la liste d'initialisation:struct MyClass {const map<int, int> m; MyClass(); }; MyClass::MyClass() : m(create_map())
Ce n'est pas un problème compliqué de créer quelque chose de similaire à stimuler. Voici une classe avec seulement trois fonctions, y compris le constructeur, pour reproduire ce que boost a fait (presque).
Usage:
Le code ci-dessus fonctionne mieux pour l'initialisation de variables globales ou de membres statiques d'une classe qui doit être initialisée et vous ne savez pas quand il sera utilisé en premier, mais vous voulez vous assurer que les valeurs y sont disponibles.
Si disons, vous devez insérer des éléments dans une carte std :: map existante ... voici une autre classe pour vous.
Usage:
Voyez-le en action avec GCC 4.7.2 ici: http://ideone.com/3uYJiH
############### TOUT CI-DESSOUS C'EST OBSOLÈTE #################
EDIT : La
map_add_values
classe ci-dessous, qui était la solution originale que j'avais suggérée, échouerait en ce qui concerne GCC 4.5+. Veuillez consulter le code ci-dessus pour savoir comment ajouter des valeurs à la carte existante.Usage:
REMARQUE: Auparavant, j'utilisais un
operator []
pour ajouter les valeurs réelles. Ce n'est pas possible comme l'a commenté dalle.##################### FIN DE LA SECTION OBSOLETE #####################
la source
operator[]
ne prend qu'un seul argument.error: conflicting declaration ‘map_add_values<int, int> my_map’
error: ‘my_map’ has a previous declaration as ‘std::map<int, int> my_map’
Voici une autre façon d'utiliser le constructeur de données à 2 éléments. Aucune fonction n'est nécessaire pour l'initialiser. Il n'y a pas de code tiers (Boost), pas de fonctions ou d'objets statiques, pas de trucs, juste du C ++ simple:
Depuis que j'ai écrit cette réponse, C ++ 11 est sorti. Vous pouvez maintenant initialiser directement les conteneurs STL à l'aide de la nouvelle fonctionnalité de liste d'initialisation:
la source
Par exemple:
Si map est un membre de données d'une classe, vous pouvez l'initialiser directement dans l'en-tête de la manière suivante (depuis C ++ 17):
la source
J'envelopperais la carte dans un objet statique et mettrais le code d'initialisation de la carte dans le constructeur de cet objet, de cette façon, vous êtes sûr que la carte est créée avant l'exécution du code d'initialisation.
la source
Je voulais juste partager un pur travail C ++ 98:
la source
Tu peux essayer:
la source
{1, 2}
place destd::pair<int, int>(1, 2)
.Ceci est similaire à
PierreBdR
, sans copier la carte.la source
Si vous êtes coincé avec C ++ 98 et que vous ne souhaitez pas utiliser boost, voici la solution que j'utilise lorsque j'ai besoin d'initialiser une carte statique:
la source
Vous avez de très bonnes réponses ici, mais je suis pour moi, cela ressemble à un cas de "quand tout ce que vous savez c'est un marteau" ...
La réponse la plus simple à la raison pour laquelle il n'y a pas de moyen standard d'initialiser une carte statique, c'est qu'il n'y a aucune bonne raison d'utiliser une carte statique ...
Une carte est une structure conçue pour une recherche rapide, d'un ensemble inconnu d'éléments. Si vous connaissez les éléments à l'avance, utilisez simplement un tableau C. Entrez les valeurs de manière triée ou exécutez le tri sur celles-ci si vous ne pouvez pas le faire. Vous pouvez ensuite obtenir les performances de log (n) en utilisant les fonctions stl :: pour boucler les entrées, lower_bound / upper_bound. Lorsque j'ai testé cela auparavant, ils fonctionnent normalement au moins 4 fois plus vite qu'une carte.
Les avantages sont multiples ... - des performances plus rapides (* 4, j'ai mesuré sur de nombreux types de CPU, c'est toujours autour de 4) - un débogage plus simple. Il est simplement plus facile de voir ce qui se passe avec une disposition linéaire. - Implémentations triviales d'opérations de copie, si cela devenait nécessaire. - Il n'alloue aucune mémoire au moment de l'exécution, donc ne lèvera jamais d'exception. - Il s'agit d'une interface standard et est donc très facile à partager entre les DLL, les langues, etc.
Je pourrais continuer, mais si vous en voulez plus, pourquoi ne pas consulter les nombreux blogs de Stroustrup sur le sujet.
la source
map
est également une forme utile pour représenter une fonction partielle (fonction au sens mathématique; mais aussi, en quelque sorte, au sens de la programmation). Un tableau ne fait pas cela. Vous ne pouvez pas, par exemple, rechercher des données à partir d'un tableau à l'aide d'une chaîne.