map Zugriff immer per find()?



  • Hallo!

    wenn ich eine map foo habe und ich weiß sicher, dass es für einen Key K ein Eintrag in der map is, sollte ich dann den Value dennoch per foo.find(k) machen oder gleich per Value v = foo[k]?



  • In dem Fall ruhig per operator[], also dein Value v = foo[k].
    Edit: Der Vollständigkeit halber: Wenn du mit [] zugreifst, und noch kein Eintrag zu dem Key existiert, wird er mit seinem default ctor erzeugt und eingefügt, und auf den würdest du dann Zugreifen.



  • Zugriffer schrieb:

    Hallo!

    wenn ich eine map foo habe und ich weiß sicher, dass es für einen Key K ein Eintrag in der map is

    gibt, meinst du. Und das dick geschriebene setzt das auch voraus, ne? Dann kannst du gleich zum Index-Operator übergehen. Wenn du wissen willst, ob es schon drin ist (und ggf. darauf zugreifen), nimm zuerst count() und dann operator[] .


  • Mod

    Hacker schrieb:

    Wenn du wissen willst, ob es schon drin ist (und ggf. darauf zugreifen), nimm zuerst count() und dann operator[] .

    Häh? Wieso willst du zweimal eine Suchaktion durchführen? Wenn du wissen willst, ob es schon drin ist (und ggf. darauf zugreifen), dann nimm bitte find. Und wenn du schon weißt, dass es drin ist, dann ist es herzlich egal, operator[] ist ein bisschen kürzer zu schreiben, erlaubt jedoch keinen const-Zugriff. Will man mehrmals nacheinander auf das gleiche Element zugreifen natürlich sowieso find.

    Wobei sich allgemein fragt, wie man vorher schon weiß, dass ein Element ganz sicher drin ist. Oft heißt das nämlich, es ist vorher schon ein find oder count erfolgt und man hätte beides in einem Rutsch mit find machen können.



  • SeppJ schrieb:

    Hacker schrieb:

    Wenn du wissen willst, ob es schon drin ist (und ggf. darauf zugreifen), nimm zuerst count() und dann operator[] .

    Häh? Wieso willst du zweimal eine Suchaktion durchführen? Wenn du wissen willst, ob es schon drin ist (und ggf. darauf zugreifen), dann nimm bitte find. Und wenn du schon weißt, dass es drin ist, dann ist es herzlich egal, operator[] ist ein bisschen kürzer zu schreiben, erlaubt jedoch keinen const-Zugriff. Will man mehrmals nacheinander auf das gleiche Element zugreifen natürlich sowieso find.

    Aber

    if(meinemap.count(key)) a = meinemap[key];
    
    if(std::map<keytype, valuetype>::iterator iter = meinemap.find(key) != meinemapap.end())
        a = *iter;
    

    Du hast Recht, mit find ist es effektiver. 😞



  • if(meinemap.count(key)) a = meinemap[key];
    
    if(std::map<keytype, valuetype>::iterator iter = meinemap.find(key) != meinemapap.end())
        a = *iter;
    

    Ich benutze bei den iteratoren immer ganz gerne "auto". Ist schneller zu schreiben und der code ist besser wiederverwendbar falls man mal die definition der map (template-parameter) ändern sollte.

    Also wie folgt:

    if( (auto iter = meinemap.find(key)) != meinemapap.end()) //die Zuweisung sollte geklammert werden
        a = iter->second; //*iter würde doch das std::pair liefern?
    

    Alternativ (oder am besten zusätzlich) ein typedef für die map, also typedef std::map<myKey, myVal> myMap;



  • RedPuma schrieb:

    if(meinemap.count(key)) a = meinemap[key];
    
    if(std::map<keytype, valuetype>::iterator iter = meinemap.find(key) != meinemapap.end())
        a = *iter;
    

    Ich benutze bei den iteratoren immer ganz gerne "auto".

    Ich auch (sogar auch bei ganz anderen Sachen). C++11 ist generell ziemlich geil. Glaub mir, ich hab das so nur wegen dem Anfänger gemacht (der bestimmt keinen C++11-Compiler hat). 😃



  • RedPuma schrieb:

    //die Zuweisung sollte geklammert werden
        a = iter->second; //*iter würde doch das std::pair liefern?
    

    1. Sollte nicht nur, muss! Das Gleichheitszeichen geht nach dem Gleichwertigkeits-Vergleichsoperator. (Edit: Aber... Kann man einen Boolean überhaupt implizit in einen iterator casten?/Gibts dafür einen ZuweisungsOperator bzw. ctor? Compiliert nähmlich...)
    2. Da hast du natürlich Recht, sry



  • Hacker schrieb:

    Ich auch (sogar auch bei ganz anderen Sachen). C++11 ist generell ziemlich geil. Glaub mir, ich hab das so nur wegen dem Anfänger gemacht (der bestimmt keinen C++11-Compiler hat). 😃

    Huh? Gerade als Anfänger hat man doch nen C++11 Compiler, da man nicht ewig auf alter Software rumsitzt.

    Mit 'auto' wäre dein Code wenigstens nicht falsch, du hast 'typename' vergessen. 😉



  • Ethon schrieb:

    Mit 'auto' wäre dein Code wenigstens nicht falsch, du hast 'typename' vergessen. 😉

    Ne, hat er nicht. Wo sollte denn das typename deiner Meinung nach hin?

    Der Code ist aber trotzdem falsch, man kann das nicht klammern:

    if (int i = 5); // ok
    if ((int i = 5)); // Compiler Fehler
    

    Du wirst die Variable vorher deklarieren müssen.



  • Hacker schrieb:

    RedPuma schrieb:

    //die Zuweisung sollte geklammert werden
        a = iter->second; //*iter würde doch das std::pair liefern?
    

    1. Sollte nicht nur, muss! Das Gleichheitszeichen geht nach dem Gleichwertigkeits-Vergleichsoperator. (Edit: Aber... Kann man einen Boolean überhaupt implizit in einen iterator casten?/Gibts dafür einen ZuweisungsOperator bzw. ctor? Compiliert nähmlich...)

    Es wird nur mit *a = iter kompilieren, da iter wie gesagt ein boolean währe, dieser boolean wird als Adresse interpretiert, welche dann dereferenziert wird. Sinnhaftigkeit ist aber keine vorhanden 😉


Anmelden zum Antworten