Globale Initialisierung



  • Hallo,
    ich will in einem Header eine globale const map<char, char> definieren, die Decodierungs-Informationen enthält.

    Der einzige Weg, der mir einfällt, wäre dieser:

    map<char, char> initialize_foo()
    {
    	map<char, char> result;
    	result['a'] = '7';
    	result['b'] = '2';
    	//...
    	return result;
    }
    
    const map<char, char> foo = initialize_foo();
    

    Allerdings finde ich es blöd, wenn ich für jede globale Variable eine neue Funktion schreiben muss.
    Gibt es da keinen besseren Weg?



  • Wurstinator schrieb:

    Gibt es da keinen besseren Weg?

    1. Keine globalen Variablen verwenden
    2. Pack deine Map in eine Klasse und verwend den Konstruktor...


  • Mit C++11 kannst du sie so initialisieren:

    std::map<char, char> mymap = { { 'a', 'b' }, { 'c', 'd' }, { 'e', 'f' } };
    


  • Wurstinator schrieb:

    Gibt es da keinen besseren Weg?

    namespace {
    struct init {
        init() {
            // Allen Initialisierungscode hier rein.
        }
    } dummy;
    }
    

    Kurze Erklärung: Das "namespace" verhindert die Sichtbarkeit der Symbole "init" und "dummy" in anderen Übersetzungseinheiten. Der Konstruktor der struct wird aufgerufen, weil ja die Instanz "dummy" deklariert wird.



  • @ dot: Und Alternativen zu globalen Variablen wären... ?
    Eine Klasse nur für diese Variable ist doch noch unschöner als eine Funktion.

    @ 314159265358979: C++11 hab ich leider nicht.

    @ asdasdasd: Wenn ich ein struct verwende, müsste ich dann nicht alle Funktionen von map, die ich verwenden will, dort neu schreiben?



  • Wurstinator schrieb:

    @ asdasdasd: Wenn ich ein struct verwende, müsste ich dann nicht alle Funktionen von map, die ich verwenden will, dort neu schreiben?

    Nein, das Ganze bietet dir einfach nur einen Funktionskörper, den du für deinen Code nutzen kannst.

    Ich sehe aber gerade, dass du deine Variable "foo" im Ausgangspost "const" gemacht hast. Dann funktioniert die von mir gezeigte Methode nicht.



  • Wurstinator schrieb:

    @ dot: Und Alternativen zu globalen Variablen wären... ?
    Eine Klasse nur für diese Variable ist doch noch unschöner als eine Funktion.

    Wenn ein Objekt ein anderes Objekt benutzen will, ihm eine Referenz drauf zu geben...



  • Gibt es einen speziellen Grund, warum du eine std::map<char, char> statt eines char[256] haben willst? Ein Interface ist da ja schnell herumgeschustert, und Lookup wäre damit trivial. Ich stelle mir das etwa so vor:

    namespace {
      struct decode_info_t {
        decode_info_t() {
          (*this)
            ('a', '7')
            ('b', '2')
    	// ...
    	;
        }
    
        char operator[](char c) const { return data[static_cast<unsigned char>(c)]; }
    
      private:
        decode_info_t &operator()(char c, char d) {
          data[static_cast<unsigned char>(c)] = d;
        }
    
        char data[256];
      } const decode_info;
    }
    
    // ...
    
    assert(decode_info['a'] == '2');
    


  • @ dot: Und dann soll ich dieses Objekt in main() erzeugen und an jede Unterfunktion und jedes Unterobjekt weitergeben?
    Nein danke.

    @ seldon: Die Map ist nur ein Beispiel, das ich gerade brauche, für das Problem. Ich hatte auch schon kompliziertere Fälle.



  • Da niemand mehr antwortet, gehe ich davon aus, dass es keine bessere Lösung gibt?



  • Boost.Assign wäre eine mögliche Lösung.

    bzw. etwas selbstgebasteltes nach dem Boost.Assign Gedanken.

    Prinzipiell habe ich idR etwas derartiges:

    map<string, int> m = initializer<map<string, int> >
      ("hallo", 7)
      ("welt", 3)
      ("foo", 8)
      ("bar", 12)
    ;
    


  • Hol' dir nen ordentlichen Compiler.



  • Boost.Assign sieht schon ganz gut aus. Ich werde es mir mal ansehen. Danke.


Anmelden zum Antworten