Kleiner Operator: Richtig überladen?



  • Hi,

    std::pain... OOPS 🙂

    So, bitte nimm es mir nicht übel Nexus. Aber wie genau wende ich das an?

    Ich habe folgende Klasse

    class Graph
    {
    public:
    	std::map<Location, Node> nodes;
    	Graph();
    	~Graph(void);
    	void readMap(std::string fileName);
    	static void test();
    	//Routenberechnung
    	List<Location>& bfSearchForShortestPath(const Location& s, const Location& d, List<Location>& route);
    };
    

    Füge ich nun die Funktion ein und haue den Funktionsnamen noch hinter Node, funktioniert das so aber nicht 😞



  • skizZ schrieb:

    So, bitte nimm es mir nicht übel Nexus. Aber wie genau wende ich das an?

    Wieso sollte ich es dir übel nehmen? 🙂

    Du musst das Vergleichsprädikat (Funktion oder Funktor) als drittes Templateargument bei std::map mitgeben. Also so, wie ich es oben geschrieben habe (unter "Deklaration").



  • Hi,

    wenn ich das so mache:

    #pragma once
    #include <map>
    #include <string>
    #include "Node.h"
    #include "List.h"
    
    bool CompareLocations(const Location& Left, const Location& Right)
    {
        if (Left.xAxis != Right.xAxis)
            return Left.xAxis < Right.xAxis;
        else
            return Left.yAxis < Right.yAxis;
    }
    
    class Graph
    {
    public:
    	std::map<Location, Node, CompareLocations> nodes;
    	Graph();
    	~Graph(void);
    	void readMap(std::string fileName);
    	static void test();
    	//Routenberechnung
    	List<Location>& bfSearchForShortestPath(const Location& s, const Location& d, List<Location>& route);
    };
    

    Bekomm ich

    c:\dokumente und einstellungen\florian\eigene dateien\visual studio 2005\projects\futurecar_1\graph.h(18) : error C2923: "std::map": "CompareLocations" ist kein gültiges template-Typargument für den _Pr-Parameter.
            c:\dokumente und einstellungen\florian\eigene dateien\visual studio 2005\projects\futurecar_1\graph.h(7): Siehe Deklaration von 'CompareLocations'
    c:\dokumente und einstellungen\florian\eigene dateien\visual studio 2005\projects\futurecar_1\graph.cpp(16) : error C2084: Funktion 'bool CompareLocations(const Location &,const Location &)' hat bereits einen Funktionsrumpf
            c:\dokumente und einstellungen\florian\eigene dateien\visual studio 2005\projects\futurecar_1\graph.h(7): Siehe vorherige Definition von 'CompareLocations'
    

    😞



  • Sorry, ich habe vorhin was Falsches erzählt, ich habe es mit den Sortierfunktionen verwechselt.

    Als drittes Template-Argument muss der Funktionstyp angegeben werden. Das ist ein Zeiger auf eine Funktion, die einen bool zurückgibt und zwei Const-Referenzen auf Location als Parameter hat:

    typedef bool (*FunctionType) (const Location&, const Location&);
    

    Die Deklaration sieht dann so aus:

    std::map<Location, Node, FunctionType> Map(CompareLocations);
    

    Wie du siehst, wird die eigentliche Funktion als Konstruktorargument der map übergeben.

    Edit: Ich habe den Fehler in meinem oberen Post korrigiert.



  • Hi,

    sorry, aber er zeigt mir hier

    std::map<Location, Node, FunctionType> nodes(CompareLocations);
    

    noch immer an: error C2061: Syntaxfehler: Bezeichner 'CompareLocations'



  • Versuch mal

    std::map<Location, Node, FunctionType> nodes(&CompareLocations);
    

    Die Funktion heisst ja schon so, oder?



  • Hi,

    nee das funktioniert auch nicht 😞

    hier nochmal der schnipsel

    bool CompareLocations(const Location& Left, const Location& Right)
    {
        if (Left.xAxis != Right.xAxis)
            return Left.xAxis < Right.xAxis;
        else
            return Left.yAxis < Right.yAxis;
    }
    
    class Graph
    {
    public:
    	typedef bool (*FunctionType) (const Location&, const Location&);  // Funktionszeiger als Typ
        std::map<Location, Node, FunctionType> nodes(CompareLocations);
    


  • Ah, du kannst den Konstruktor natürlich nicht bei der Deklaration aufrufen. 😉

    Schreib in die Klassendefinition:

    typedef bool (*FunctionType) (const Location&, const Location&);
    std::map<Location, Node, FunctionType> nodes;
    

    Und in den Konstruktor:

    Graph::Graph()
    : nodes(CompareLocations)
    {
    
    }
    


  • skizZ schrieb:

    Hi,

    wenn ich das so mache:

    #pragma once
    #include <map>
    #include <string>
    #include "Node.h"
    #include "List.h"
    
    bool CompareLocations(const Location& Left, const Location& Right)
    {
        if (Left.xAxis != Right.xAxis)
            return Left.xAxis < Right.xAxis;
        else
            return Left.yAxis < Right.yAxis;
    }
    
    class Graph
    {
    public:
    	std::map<Location, Node, CompareLocations> nodes;
    	Graph();
    	~Graph(void);
    	void readMap(std::string fileName);
    	static void test();
    	//Routenberechnung
    	List<Location>& bfSearchForShortestPath(const Location& s, const Location& d, List<Location>& route);
    };
    

    😞

    CompareLocations muss ein Funktor sein, sonst geht es nicht als Templateargument:

    struct CompareLocations
    {
    bool operator()(const Location& Left, const Location& Right)
        {
            if (Left.xAxis != Right.xAxis)
                return Left.xAxis < Right.xAxis;
            else
                return Left.yAxis < Right.yAxis;
        }
    };
    
    class Graph
    {
    public:
        std::map<Location, Node, CompareLocations> nodes;
        //...
    };
    


  • Tachyon schrieb:

    CompareLocations muss ein Funktor sein, sonst geht es nicht als Templateargument:

    Nein, es geht auch mit einer Funktion. Nur muss man da eben den Funktionszeiger-Typen als Template-Argument angeben, so wie ich das gezeigt habe.

    bool CompareLocations(const Location& Left, const Location& Right)
    { 
        if (Left.xAxis != Right.xAxis) 
            return Left.xAxis < Right.xAxis; 
        else 
            return Left.yAxis < Right.yAxis;
    }
    
    int main()
    {
    	typedef bool (*Function) (const Location&, const Location&);
    	std::map<Location, float, Function> Map(&CompareLocations);
    }
    


  • Danke,

    nun funktioniert es 😃


Anmelden zum Antworten