Ich brauche nur ein Wörterbuch oder ein assoziatives Array string
=> int
.
Für diesen Fall gibt es die Typzuordnung C ++.
Aber ich brauche nur eine Map für alle Instanzen (-> statisch) und diese Map kann nicht geändert werden (-> const);
Ich habe diesen Weg mit der Boost-Bibliothek gefunden
std::map<int, char> example =
boost::assign::map_list_of(1, 'a') (2, 'b') (3, 'c');
Gibt es eine andere Lösung ohne diese Bibliothek? Ich habe so etwas versucht, aber es gibt immer einige Probleme mit der Karteninitialisierung.
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
.Antworten:
quelle
Boost.Assign
ziemlich ordentlich , ein ähnliches Design zu verwenden :)cout << A::myMap[1];
inmain()
. Es gibt einen Fehler. Der Fehler tritt nicht auf, wenn ich dieconst
Qualifikationsmerkmale entferne. Ich denke, dass Map's zumindest in der g ++ - Implementierung der C ++ - Bibliothekoperator[]
nicht mit a umgehen könnenconst map
.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]
Der C ++ 11-Standard führte eine einheitliche Initialisierung ein, die dies viel einfacher macht, wenn Ihr Compiler dies unterstützt:
Siehe auch diesen Abschnitt aus Professional C ++ unter unordered_maps.
quelle
Ich hab es gemacht! :) :)
Funktioniert gut ohne C ++ 11
quelle
Wenn Sie es
boost::assign::map_list_of
nützlich finden , es aber aus irgendeinem Grund nicht verwenden können, können Sie Ihr eigenes schreiben :Es ist nützlich zu wissen, wie solche Dinge funktionieren, besonders wenn sie so kurz sind, aber in diesem Fall würde ich eine Funktion verwenden:
a.hpp
a.cpp
quelle
Eine andere Herangehensweise an das Problem:
Dies ist effizienter, da es keine Kopie eines Typs vom Stapel zum Heap gibt (einschließlich Konstruktor, Destruktoren für alle Elemente). Ob dies wichtig ist oder nicht, hängt von Ihrem Anwendungsfall ab. Bei Saiten spielt das keine Rolle! (aber Sie können diese Version "sauberer" finden oder auch nicht)
quelle
Wenn die Karte nur Einträge enthalten soll, die zur Kompilierungszeit bekannt sind, und die Schlüssel für die Karte Ganzzahlen sind, müssen Sie überhaupt keine Karte verwenden.
quelle
switch
ist allerdings schrecklich. Warum nichtreturn key + 'a' - 1
?return key + 'a' - 1
dies für sein eigentliches Mapping nicht funktionieren würde.Sie könnten dies versuchen:
MyClass.h
MyClass.cpp
Mit dieser Implementierung ist die statische Map Ihrer Klassenkonstante ein privates Mitglied und kann mithilfe einer öffentlichen get-Methode für andere Klassen zugänglich sein. Andernfalls können Sie die public get-Methode entfernen und die Map-Variable in den öffentlichen Abschnitt der Klasse verschieben, da sie konstant ist und sich nicht ändern kann. Ich würde jedoch die createMap-Methode privat oder geschützt lassen, wenn Vererbung und / oder Polymorphismus erforderlich sind. Hier sind einige Anwendungsbeispiele.
Ich hatte meinen ursprünglichen Beitrag bearbeitet, es war nichts Falsches an dem ursprünglichen Code, in dem ich ihn gepostet habe, kompiliert, erstellt und korrekt ausgeführt. Es war nur so, dass meine erste Version, die ich als Antwort präsentierte, die Karte als öffentlich deklariert wurde und die Karte war const war aber nicht statisch.
quelle
Wenn Sie einen Compiler verwenden, der die universelle Initialisierung immer noch nicht unterstützt, oder wenn Sie Bedenken haben, Boost zu verwenden, ist eine andere mögliche Alternative die folgende
quelle
Ein Funktionsaufruf kann nicht in einem konstanten Ausdruck erscheinen.
versuchen Sie dies: (nur ein Beispiel)
quelle
static map<int,int> myMap = create_map();
falsch.struct testdata { testdata(int){} }; struct test { static const testdata td = 5; }; testdata test::td;
Sie kann nicht kompiliert werden, selbst wenn die Initialisierung mit einem konstanten Ausdruck (5
) durchgeführt wird. Das heißt, "konstanter Ausdruck" ist für die Richtigkeit (oder das Fehlen) des ursprünglichen Codes irrelevant.Ich benutze dieses Muster oft und empfehle Ihnen, es auch zu verwenden:
Sicher ist es nicht sehr lesbar, aber ohne andere Bibliotheken ist es das Beste, was wir tun können. Es wird auch keine redundanten Vorgänge wie das Kopieren von einer Karte auf eine andere geben, wie bei Ihrem Versuch.
Dies ist innerhalb von Funktionen noch nützlicher: Anstelle von:
Verwenden Sie Folgendes:
Sie müssen sich hier nicht nur nicht mehr mit booleschen Variablen befassen, sondern haben auch keine versteckte globale Variable, die überprüft wird, ob der Initialisierer der statischen Variablen innerhalb der Funktion bereits aufgerufen wurde.
quelle