Map mit std::pair als Key, Zugriff funktioniert nicht



  • Hallo,

    Ich habe eine Map, welche Objekte einer zuvor selbst erstellten Klasse in einem Koordinatensystem (X,Y) abspeichert.
    Der Key ist also ein Signed Integer Pair mit den Werten x und y.

    Key: std::pair<signed int, signed int>
    

    Der Code schaut so aus:

    std::map< std::pair<signed int, signed int>, MyClass > field;
    
    // Objekt hinzufügen, funktioniert einwandfrei:
    field.insert(std::make_pair(std::make_pair(x,y), *MyClass));
    
    // Prüfen, ob Objekt vorhanden ist, funktioniert ebenfalls:
    if (field.count(std::make_pair(x,y)) == 1)
    {
      -> Objekt vorhanden.
    }
    

    Soweit funktioniert alles. Doch sobald ich auf ein gespeichertes Objekt in der Map zugreifen will, kommt eine Fehlermeldung 😞

    MyClass objekt = field[std::make_pair(x,y)];
    

    Ich weiß nicht, was an dieser Zeile falsch ist. Ich bin mir absolut sicher, dass das Element, auf welches ich zugreifen will, in der Map existiert...

    Fehlermeldung:
    *
    In instantiation of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::pair<int, int>; _Tp = Tile; _Compare = std::less<std::pair<int, int> >; _Alloc = std::allocator<std::pair<const std::pair<int, int>, Tile> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Tile; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]':| required from here|
    *

    Danke für eure Hilfe, Mfg Mike


  • Mod

    Mike100 schrieb:

    In instantiation of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::pair<int, int>; _Tp = Tile; _Compare = std::less<std::pair<int, int> >; _Alloc = std::allocator<std::pair<const std::pair<int, int>, Tile> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Tile; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]':| required from here|

    Das ist keine (vollständige) Fehlermeldung.



  • ||=== Build: Debug (compiler: GNU GCC Compiler) ===|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_map.h||In instantiation of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::pair<int, int>; _Tp = Tile; _Compare = std::less<std::pair<int, int> >; _Alloc = std::allocator<std::pair<const std::pair<int, int>, Tile> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Tile; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]':|
    C:\Users\map.cpp|46|required from here|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_map.h|472
    *
    *
    |error: no matching function for call to 'MyClass::MyClass()'|
    ||=== Build failed: 1 error(s), 2 warning(s) (0 minute(s), 1 second(s)) ===|

    Hier die vollständige Fehlermeldung. Er versucht seltsamerweise, ein neues Objekt zu erzeugen und scheitert an den fehlenden Argumenten im Konstruktor. Ich will aber nur ein vorhandenes Objekt aufrufen, welches in der Map gespeichert ist.

    Noch einmal zur genaueren Verdeutlichung:

    // Speichert Objekt in der Map dynamisch ab, funktioniert sicher:
    MyClass *objekt = new MyClass(arg1,arg2);
    field.insert(std::make_pair(std::make_pair(x,y), *objekt));
    
    // Zugriff auf dieses Objekt schlägt fehl:
    MyClass new_object = field[std::make_pair(x,y)];
    


  • Das geht nicht mit dem [] -Operator. Der legt ein neues Element an, wenn keins für den Schlüssel existiert. Der Compiler benötigt hier den Standardkonstruktor unabhängig davon, ob er zur Laufzeit tatsächlich aufgerufen wird oder nicht.
    Wenn du nur ein Element abfragen möchtest, nimm die find -Methode.



  • Danke Tyroxx du hast mich auf den entscheidenten Punkt gebracht!

    Der []-Operator funktioniert mit Maps nicht auf diese Art, wie er bei einem Array funktionieren würde. Ich habe es jetzt ganz einfach mit der Methode map::at gelöst.

    Der Grund, warum ich hier überhaupt in die Falle gegangen bin, liegt an den ganzen schlecht geschriebenen Tutorials und Beispieldateien, die im Internet verstreut zu finden sind.

    Überall steht map[key], als würde es ganz normal funktionieren.

    Die Tutorialsersteller sind nicht einmal fähig, dass sie den Code, den sie Anfängern zur Verfügung stellen, vorher kompilieren, deshalb kommt so ein Schwachsinn heraus! 😡 😡 😡



  • Also wenn du solche "Tutorials" meinst, dann heissen die zum ersten Referenzen und zweitens steht da auch, was gebraucht wird oder was passiert, nämlich in dem Fall, dass der Standardkonstruktor genutzt und aufgerufen wird.



  • Mike100 schrieb:

    Überall steht map[key], als würde es ganz normal funktionieren.

    Tut es ja auch. Das Problem ist nur, wenn kein Wert für key in der Map drin ist, wird einer mit dem Default-Konstruktor erstellt. Für Typen, die einen Defaultkonstruktor haben (das sind die meisten), geht das dann auch problemlos.
    Schiebs nicht auf die Tutorials.



  • Mit Tutorial meine ich natürlich nicht die offizielle C++-Referenz, sondern wahllose Codeausschnitte von "Drittanbietern".



  • Ja dann kannste ja nichts erwarten.


Log in to reply