std::map mit eigener Klasse als Schlüssel



  • Du kannst das Problem einfach lösen, indem du dir den Constructor von std::map einmal komplett anschaust.

    template <
        class Key,
        class T,
        class Compare = std::less<Key>, // der Punkt ist für dich interessant
        class Allocator = std::allocator< std::pair<const Key, T> >
    > class map;
    

    http://www.cplusplus.com/forum/general/4444/

    Bei den Operatoren kann ich dir nicht helfen, sollte aber gehen.



  • Der erste Operator sollte funktionieren. Wenn du den zweiten benutzen willst, sollte er const sein. Was du in deinen Codeschnippseln nicht zeigst: was ist vc und wo sind die Operatoren definiert?



  • Nick hat im Bezug auf den Operator unrecht.

    Edit: Wobei mir beim weiteren Nachdenken Zweifel kommen, ob der Compiler wirklich bei dem ersten Fund auf der Suche nach einem Operator schluss machen darf. Aber irgendwie ist das auch egal, weil es doch gar keinen Sinn macht, den Vergleichsoperator als nicht-const-Methode zu implementieren, vor allem wenn die freistehende Funktion das dann auf einmal doch kann.



  • AlexSpritze schrieb:

    std::map<Point, Vec3f> data;
    

    error C2678: Binärer Operator '<': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'const vc::Point' akzeptiert (oder keine geeignete Konvertierung möglich)

    bool operator < (const Point& p1, const Point& p2){...}
    

    Das sieht schon mal nicht schlecht aus. Es müsste funktionieren, wenn Du dies als freie Funktion in demselben Namensraum wie Deine Klasse Point deklarierst. Das mit dem Namensraum ist wichtig. Stichwort ADL (argument-dependent-lookup).

    AlexSpritze schrieb:

    bool Point::operator< (Point& p) {...}
    

    Das soll wohl eine nicht-statische Elementfunktion sein. Hier fehlen die zwei const s:

    bool Point::operator< (Point const& p) const {...}
    

    Natürlich darfst Du nur eine der beiden Varianten verwenden. Aus Symmetriegründen macht man das typischerweise mit einer freien Funktion.



  • Decimad schrieb:

    Nick hat im Bezug auf den Operator unrecht.

    😕 Wie meinen?
    Ich hab mir die Operatoren nicht angesehen, weil ich mich damit nicht beschäftigt habe. Aber ein richtig formulierter und sinnvoller "kleiner als"-Operator sollte funktionierten. Nichts anderes passiert bei den Integralen Typen.



  • Naja, ich hatte das so interpretiert, dass du meintest dass es mit diesen (also denen vom TE) funtionieren sollte. Sorry falls ich das missverstanden habe.



  • @krümel: Ist die Symmetrie da echt so toll, dass man da so viele friend-Deklarationen in Kauf nimmt? Hab den Quelltext anderer noch nicht nach diesem Aspekt durchwühlt.



  • Decimad schrieb:

    Edit: Wobei mir beim weiteren Nachdenken Zweifel kommen, ob der Compiler wirklich bei dem ersten Fund auf der Suche nach einem Operator schluss machen darf.

    Die Suche findet "von innen nach außen" bzgl Gültigkeitsbereiche statt. Wird in einem Gültigkeitsbereich der Name gefunden, wird gestoppt. Ist der Compiler im globalen Gültigkeitsbereich gelandet, werden auch schließlich alle über using-Direktiven "eingebundenen" Namensräume durchsucht. Schließlich werden noch assoziierte Namensräume durchsucht (ADL). Es gibt aber auch eine Ausnahme, wo ADL nicht greift. Dass bei einem Fund die übergeordneten Gültigkeitsbereiche nicht mehr abgesucht werden führt zu dem "Hiding"-Effekt.

    Lesetipps:
    http://www.gotw.ca/publications/mill02.htm
    http://www.gotw.ca/publications/mill08.htm



  • Decimad schrieb:

    @krümel: Ist die Symmetrie da echt so toll, dass man da so viele friend-Deklarationen in Kauf nimmt?

    Eine freie Funktion muss natürlich keine friend-Funktion sein. Ich würde eher erwarten, dass die Schnittstelle der Klasse Point all die für einen Vergleich nötigen Informationen rausrückt.



  • Da hast du natürlich Recht. *ditsch*
    Edit: Wobei mich das Gefühl beschleicht, dass man da irgendwann doch unter Umständen Implementierungsdetails nach außen durchschleifen muss, dafür.


Anmelden zum Antworten