2016-04-04 4 views
1

Ich versuche, ein std::unordered_map mit einer enum class als Schlüssel und eine definierte Klasse wie das referenzierte Objekt zu definieren:std :: unordered_map Enum mit und definierte Klasse

std::unordered_map<Dimension, unit, EnumClassHash> SI_Dim; 
SI_Dim[Dimension::MASS] = BaseSIUnits::kilogram; 

Dimension ist ein enum class in einem separaten erklärt Header-Datei als

enum class Dimension{MASS, TIME, LENGTH, TEMPERATURE, CURRENT, QUANTITY, ANGLE, FORCE, ENERGY, POWER, 
       AREA, VOLUME, NONDIMENSIONAL}; 

mit EnumClassHash als Hash-Funktion (die ich den Code für Beiträge schreiben kann, wenn es relevant ist).

BaseSIUnits::kilogram ist ein paar Zeilen darüber, wie

const unit BaseSIUnits::kilogram = unit(1, "kg", Dimension::MASS); 

definiert, die gerade fein kompiliert. Aber die SI_Dim[Dimension::MASS] = BaseSIUnits::kilogram; Zeile gibt mir einen Fehler. In QtCreator (meine IDE) heißt es "erwartet eine Deklaration" und g ++ gibt den Fehler "SI_Dim nennt keinen Typ". Für mich ergibt das keinen Sinn. Wenn man sich die Zeile in QtCreator ansieht, wird weder Dimension::MASS noch BaseSIUnits::kilogram hervorgehoben (fast so, als ob sie nicht erkannt würden, obwohl ich weiß, dass sie es sind). Ich habe nicht viel Erfahrung mit std :: unordered_map, also ist dies wahrscheinlich ein einfacher Syntaxfehler, der mir fehlt. Aber die Syntax sieht auf der Grundlage von Beispielen, die ich mir angeschaut habe, richtig aus.

+1

Sorry, ich denke die Frage ist hier nicht klar. Meine Frage ist, ob es einen offensichtlichen Syntaxfehler gibt, der die Kompilierung des Codes verhindert. –

+4

Haben Sie diese Zeile 'SI_Dim [Dimension :: MASS] = BaseSIUnits :: Kilogramm;' außerhalb einer Funktion? Sie können nicht nur willkürlichen Code im Namespacebereich haben. – Praetorian

+0

Ich habe es außerhalb einer Funktion. Ich möchte, dass der Container unordered_map von anderen Dateien aus zugänglich ist. Wie mache ich das? –

Antwort

1

Wie Prätorianer im Kommentar bemerkt haben, können Sie nicht wirklich Code außerhalb von Funktionen in C++ haben (außer beim Initialisieren von globalen/statischen Variablen). Wenn Sie solchen Code benötigen (d. H. Code, der nicht als Initialisierung geschrieben werden kann), können Sie eine Funktion init_si_dim schreiben, die vor der Verwendung (einmal) aufgerufen werden muss. Eine Methode zum Automatisieren durch ein globales Objekt einer Ad-hoc-Klasse, die die Initialisierung im Konstruktor ausführt, finden Sie unter this question.

In einer separaten Richtung, die Verwendung einer ungeordneten Karte für Ihre Art von enum, scheint ein bisschen seltsam. Da Sie so wenige Werte haben und den Werten enum keine bestimmten ganzzahligen Werte zuweisen, denke ich, dass Sie mit einem Random-Access-Container, z. B. über std::array, besser dran sind.

Betrachten Sie den folgenden Code

#include <array>                                

enum class dimension{mass, time, length}; 

inline constexpr std::size_t dimension_to_index(dimension d) 
{ 
    return static_cast<std::size_t>(d) - static_cast<std::size_t>(dimension::mass); 
} 

struct foo{}; 

std::array<foo, 1 + dimension_to_index(dimension::length)> v; 

int main() 
{ 
    v[dimension_to_index(dimension::time)]; 
} 

Wir haben die erste enum, dann eine sichere Funktion für ihre Werte auf Indizes umzuwandeln. Wir definieren dann ein array Objekt. Wie Sie in main sehen können, ist es jetzt möglich, über die enum Werte auf die array Elemente zuzugreifen.

+0

Interessant. Ich werde mir beide Alternativen ansehen. –