Ich versuche wahrscheinlich, das Unmögliche zu erreichen, aber StackExchange überrascht mich immer, also bitte versuchen Sie es:Ist eine zur Kompilierungszeit geprüfte string-to-int-Map möglich?
Ich muss einen Namen zu einer ganzen Zahl zuordnen. Die Namen (ca. 2k) sind einzigartig. Diese Liste wird weder hinzugefügt noch gelöscht, und die Werte ändern sich während der Laufzeit nicht.
Implementieren sie als const int
Variablen gibt mir Kompilierzeitüberprüfungen für Existenz und Typ. Auch das ist sehr klar und ausführlich im Code. Fehler sind leicht zu erkennen.
Implementieren sie als std::map<std::string, int>
gibt mir eine Menge Flexibilität für den Aufbau der Namen mit String-Manipulation nachschlagen. Ich kann das verwenden, um Strings als Parameter für Funktionen zu geben, die die Liste nach mehreren Werten abfragen können, indem ich Pre-/Suffixe an diese Zeichenfolge anfüge. Ich kann auch mehrere Werte durchlaufen, indem ich einen numerischen Teil des Schlüsselnamens aus der Schleifenvariablen erstelle.
Jetzt ist meine Frage: Gibt es eine Methode, beide Vorteile zu kombinieren? Die fehlende Kompilierzeitüberprüfung (speziell für die Schlüsselexistenz) bringt für mich die zweite Methode fast zum Erliegen. (Besonders, da std::map
automatisch 0
zurückgibt, wenn der Schlüssel nicht existiert, was schwer zu findende Bugs erzeugt.) Aber die Funktionen zum Schleifen und Pre-/Suffix-Hinzufügen sind so verdammt nützlich.
Ich würde eine Lösung bevorzugen, die keine zusätzlichen Bibliotheken wie Boost verwendet, aber bitte schlagen Sie sie dennoch vor, da ich sie vielleicht trotzdem umsetzen könnte.
Ein Beispiel auf dem, was ich mit der Karte tun:
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()]);
}
Ein weiteres Ziel ist, dass der Code in der main()
Routine bleibt so einfach und ausführlichen wie möglich dargestellt. (Muss von Nicht-Programmierern verstanden werden.) Die Funktion init()
wird von einigen Tools mit Code generiert. Die doSomething(int)
Funktionen sind behoben, aber ich kann Wrapper-Funktionen um sie schreiben. Helfer wie checkName()
können komplizierter sein, müssen aber leicht debuggbar sein.
Es klingt wie Sie die Saiten zur Laufzeit konstruieren wollen, aber irgendwie zur Compile-Zeit überprüft haben? –
Es Möglichkeiten sind Aufzählungen in den entsprechenden Zeichenfolge zu konvertieren, so sollte es möglich sein .. Obwohl schwer zu sehen, wie es kompiliert Zeit ist, wenn Sie die Zeichenfolge in der Laufzeit bauen –
'std :: map' hat sicherlich die Fähigkeit, zu sagen, ob ein Element eingefügt wurde. Eine Möglichkeit ist 'Einfügen'. – chris