J'essaie probablement de réaliser l'impossible, mais StackExchange me surprend toujours, alors n'hésitez pas à tenter votre chance :
J'ai besoin de faire correspondre un nom à un nombre entier. Les noms (environ 2k) sont uniques. Il n'y aura pas d'ajouts ni de suppressions à cette liste et les valeurs ne changeront pas pendant l'exécution.
Les mettre en œuvre en tant que const int
me permet de vérifier à la compilation l'existence et le type des variables. Le code est également très clair et verbeux. Les erreurs sont facilement repérées.
Les mettre en œuvre en tant que std::map<std::string, int>
me donne une grande flexibilité pour construire les noms à rechercher avec la manipulation de chaînes de caractères. Je peux l'utiliser pour donner des chaînes comme paramètres à des fonctions qui peuvent alors interroger la liste pour des valeurs multiples en ajoutant des préfixes/suffixes à cette chaîne. Je peux également effectuer une boucle sur plusieurs valeurs en créant une partie numérique du nom de la clé à partir de la variable de boucle.
Ma question est la suivante : existe-t-il une méthode permettant de combiner ces deux avantages ? L'absence de vérification à la compilation (en particulier pour l'existence de la clé) tue presque la deuxième méthode pour moi. (D'autant plus que std::map
renvoie silencieusement 0
si la clé n'existe pas, ce qui crée des bogues difficiles à trouver). Mais les capacités de bouclage et d'ajout de pré/suffixe sont tellement utiles.
Je préférerais une solution qui n'utilise pas de bibliothèques supplémentaires comme boost, mais n'hésitez pas à les suggérer néanmoins car je pourrais les réimplémenter de toute façon.
Un exemple de ce que je fais avec la carte :
void init(std::map<std::string, int> &labels)
{
labels.insert(std::make_pair("Bob1" , 45 ));
labels.insert(std::make_pair("Bob2" , 8758 ));
labels.insert(std::make_pair("Bob3" , 436 ));
labels.insert(std::make_pair("Alice_first" , 9224 ));
labels.insert(std::make_pair("Alice_last" , 3510 ));
}
int main()
{
std::map<std::string, int> labels;
init(labels);
for (int i=1; i<=3; i++)
{
std::stringstream key;
key << "Bob" << i;
doSomething(labels[key.str()]);
}
checkName("Alice");
}
void checkName(std::string name)
{
std::stringstream key1,key2;
key1 << name << "_first";
key2 << name << "_last";
doFirstToLast(labels[key1.str()], labels[key2.str()]);
}
Un autre objectif est que le code présenté dans le main()
reste aussi simple et verbeuse que possible. (Elle doit être comprise par les non-programmeurs.) La fonction init()
sera générée par certains outils. La fonction doSomething(int)
sont fixes, mais je peux écrire des fonctions enveloppantes autour d'elles. Des aides comme checkName()
peuvent être plus complexes, mais doivent être facilement déboguables.