2009-08-04 11 views
2

Ok ... Ich habe diese Struktur und Vergleich funktions-std :: sort und binäre '=' Operator Problem mit einem C++ struct

struct Edge 
{ 
      char point1; 
      char point2; 
      int weight; 

      bool operator<(const Edge& rhs) const 
      { 
       return(weight < rhs.weight); 
      } 
}; //end Edge 

bool compareEdge(const Edge& lhs, const Edge& rhs) 
{ 
     return(lhs.weight < rhs.weight); 
} 

ich einen Vektor haben erklärt, wie ...

vector<Edge> edges; 

Schließlich versuche ich mit dem < Operator zu sortieren ...

sort(edges.begin(), edges.end()); 

und ich erhalte die folgenden Fehler in Visual Studio 2005 ...

------ Build started: Project: RadakovichLab6, Configuration: Debug Win32 ------ Compiling... graph.cpp c:\program files\microsoft visual studio 8\vc\include\algorithm(2981) : error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Edge' (or there is no acceptable conversion) 
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.h(25): could be 'Edge &Edge::operator =(const Edge &)' 
while trying to match the argument list '(const Edge, Edge)' 
c:\program files\microsoft visual studio 8\vc\include\algorithm(2997) : see reference to function template instantiation 'void std::_Insertion_sort1<_BidIt,Edge>(_BidIt,_BidIt,_Ty*)' being compiled 
with 
[ 
    _BidIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>, 
    _Ty=Edge 
] 
c:\program files\microsoft visual studio 8\vc\include\algorithm(3105) : see reference to function template instantiation 'void std::_Insertion_sort<_RanIt>(_BidIt,_BidIt)' being compiled 
with 
[ 
    _RanIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>, 
    _BidIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>> 
] 
c:\program files\microsoft visual studio 8\vc\include\algorithm(3112) : see reference to function template instantiation 'void std::_Sort<std::_Vector_const_iterator<_Ty,_Alloc>,__w64 int>(_RanIt,_RanIt,_Diff)' being compiled 
with 
[ 
    _Ty=Edge, 
    _Alloc=std::allocator<Edge>, 
    _RanIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>>, 
    _Diff=__w64 int 
] 
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.cpp(107) : see reference to function template instantiation 'void std::sort<std::_Vector_const_iterator<_Ty,_Alloc>>(_RanIt,_RanIt)' being compiled 
with 
[ 
    _Ty=Edge, 
    _Alloc=std::allocator<Edge>, 
    _RanIt=std::_Vector_const_iterator<Edge,std::allocator<Edge>> 
] c:\program files\microsoft visual studio 8\vc\include\algorithm(2988) : error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Edge' (or there is no acceptable conversion) 
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.h(25): could be 'Edge &Edge::operator =(const Edge &)' 
while trying to match the argument list '(const Edge, const Edge)' c:\program files\microsoft visual studio 8\vc\include\algorithm(2989) : error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Edge' (or there is no acceptable conversion) 
c:\documents and settings\jake\my documents\visual studio 2005\projects\radakovichlab6\graph.h(25): could be 'Edge &Edge::operator =(const Edge &)' 
while trying to match the argument list '(const Edge, Edge)' Generating Code... Compiling... main.cpp Generating Code... Build log was saved at "file://c:\Documents and Settings\Jake\My Documents\Visual Studio 2005\Projects\RadakovichLab6\Debug\BuildLog.htm" RadakovichLab6 - 3 error(s), 0 warning(s) 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

Die Frage ist in der ersten Zeile des Fehlers. Ich bekomme diesen Fehler, ob ich den überladenen Operator < verwende oder die Vergleichsfunktion an die Funktion std :: sort übergeben. Der Standard-Zuweisungsoperator der Edge-Struktur sollte ausreichen, denke ich, weil es keinen dynamisch zugewiesenen Speicher gibt. Wenn jemand eine Einsicht hat, wäre ich dankbar.

vollständige Code ...

 #include <list> 
     #include <map> 
     #include <queue> 
     #include <vector> 
     #include <algorithm> 
     #include <iostream> 

     using namespace std; 

     //the Edge and aGraph together represent the adjacency list 
     //representation of a graph. 
     struct Edge 
     { 
      char point1; //this represents the endpoint of an edge 
      char point2; 
      int weight; //this is the weight of the edge 

      bool operator<(const Edge& rhs) const 
      { 
       return(weight < rhs.weight); 
      } 
     }; //end Edge 

     class Graph 
     { 
     public: 
      //Default constructor 
      Graph(); 

      //This method inputs an edge into a graph. 
      void inputEdge(char pointA, char pointB, int wt) 
      { 
       //used to input the edges of the graph 
      Edge anEdge; 

      //prepare for insertion into list 
      anEdge.point1 = pointA; 
      anEdge.point2 = pointB; 
      anEdge.weight = wt; 

      edges.push_back(anEdge); 

      //insert edge into the adjacency list. 
      aGraph[pointA].push_front(pointB); 

      //insert the opposite direction into the 
      //adjacency list. 
      aGraph[pointB].push_front(pointA) 
      } 

      //This... 
      void bfs(); 

      //This prints a graph and is used only for debugging purposes. 
      void printGraph() const 
      { 

      list<char>::const_iterator listIter; 
      map<char, list<char>>::const_iterator mapIter; 

      for(mapIter = aGraph.begin(); 
       mapIter != aGraph.end(); 
       mapIter++) 
      { 
       for(listIter = mapIter->second.begin(); 
         listIter != mapIter->second.end(); 
         listIter++) 
       { 
        cout << mapIter->first << " " << *listIter << endl; 
       } //end for 
      } //end for 


      sort(edges.begin(), edges.end()); 

      vector<Edge>::const_iterator vectIt; 

      for(vectIt = edges.begin(); 
        vectIt != edges.end(); 
        vectIt++) 
      { 
       cout << vectIt->point1 << " " << vectIt->point2 << " " << vectIt->weight << endl; 
       } //end for 
     } //end printGraph 


     private: 
      //This is the adjacency list 
      map<char, list<char>> aGraph; 

      //This is a list of edges and their weights. 
      vector<Edge> edges; 
     }; //end Graph 

int main() 
{ 

    Graph myGraph; 

    myGraph.inputEdge('O', 'A', 2); 
    myGraph.inputEdge('O', 'B', 5); 
    myGraph.inputEdge('O', 'C', 4); 
    myGraph.inputEdge('A', 'B', 2); 
    myGraph.inputEdge('A', 'D', 7); 
    myGraph.inputEdge('B', 'D', 4); 
    myGraph.inputEdge('B', 'E', 3); 
    myGraph.inputEdge('C', 'B', 1); 
    myGraph.inputEdge('C', 'E', 4); 
    myGraph.inputEdge('E', 'D', 1); 
    myGraph.inputEdge('D', 'T', 5); 
    myGraph.inputEdge('E', 'T', 7); 
    myGraph.inputEdge('G', 'Z', 8); 

    myGraph.printGraph(); 

    cout << endl << endl; 

    system("PAUSE"); 
    return 0; 
} //end main 

Hier ist der Code ...

+0

Wir müssen die Fehlermeldungen nicht sehen, wir müssen den Code sehen, der sie verursacht hat. –

Antwort

4

Sie arbeiten mit einer const vector, die nicht sortiert werden kann. (Oder geändert).

Dies liegt daran, Ihre Funktion const ist:

void printGraph() const 

entfernen die const so Mitglieder Ihrer Klasse modifiziert werden können (und damit sortiert).

+0

Danke ... Ich kann nicht glauben, dass ich das übersehen habe! –

+4

... und genau deshalb müssen Sie den * tatsächlichen, vollständigen * Code, den Sie verwenden, angeben. :) –

+0

Danke GManNickG! Das hat mein Problem auch gelöst. Du verdienst einen goldenen Stern/danke/klopf auf den Rücken !! – Bizmarck

3

Der folgende Code kompiliert unter g ++ 4.4.0:

#include <algorithm> 
#include <vector> 
using namespace std; 

struct Edge { 
    char point1; 
    char point2; 
    int weight; 

    bool operator<(const Edge& rhs) const { 
     return(weight < rhs.weight); 
    } 
}; 

bool compareEdge(const Edge& lhs, const Edge& rhs) { 
     return(lhs.weight < rhs.weight); 
} 

int main() { 
    vector <Edge> edges; 
    sort(edges.begin(), edges.end()); 
} 

Testen Sie es mit Ihrem Compiler . Im Allgemeinen wäre es hilfreich, wenn Sie und andere kleine vollständige Programme wie diese auf den Markt bringen, die leicht getestet werden können und die das Problem (oder das Fehlen von ihnen in diesem Fall) veranschaulichen.

+0

Danke, also muss es ein Visual Studio Problem sein. –

+2

Ich glaube nicht. Haben Sie tatsächlich versucht, den von mir geposteten Code zu kompilieren? Ich denke, mit dem Code, den Sie uns nicht gezeigt haben, stimmt etwas nicht. –

+2

Derselbe obige Code wird auch in Visual Studio 2005 kompiliert. Es muss etwas anderes in Ihrem tatsächlichen Projekt von dem Code sein, den Sie in der Frage bereitstellen. – mattnewport

0

Der obige Code ist in Ordnung, es sieht so aus, als hätten Sie ein Zuweisungsproblem, wenn Sie versuchen, einem Const Edge etwas zuzuweisen.

Sie müssen keinen Zuweisungsoperator definieren, aber Sie können einem const Edge nichts zuweisen.

0

Es sieht für mich wie Sie std::sort mit einem std::vector<Edge>::const_iterator anstelle eines std::vector<Edge>::iterator, wahrscheinlich in graph.cpp Linie 107.

Nachdem ich den Code aufrufen: Die Iteratoren sind in der Tat konstant. edges ist eine Elementvariable von Graph und printGraph ist eine Const-Methode. Daher kann edges innerhalb von printGraph nicht geändert werden, da das Graph Objekt nicht durch eine Const-Methode geändert werden kann. Sortierung edges würde es ändern, so dass es zu einem Compiler-Fehler führt.

+0

... weil es ein 'const vector' ist. – GManNickG

+0

oder vielleicht in einer const Member-Funktion - aber dieses Raten bringt uns nirgendwohin - warum nicht warten, bis das OP einen Code schreibt? –

+0

Zeile 107 in graph.cpp ist sort (kanten.begin(), kanten.end()); Wenn ich diese Zeile herausnehmen, kompiliert das Programm und läuft gut. Sind begin() und end() const Iteratoren? Wenn ja, wie komme ich da rum? –

0

Die printGraph-Funktion wird als konstante Elementfunktion von Graph deklariert, aber Sie versuchen, eine Elementvariable (den Kantenvektor) zu ändern. Entfernen Sie die Konstante const aus der printGraph-Deklaration und der Code wird kompiliert.

Alternativ können Sie eine lokale Kopie des Kantenvektors erstellen und diese vor dem Ausdrucken sortieren, da die Kommentare angeben, dass diese Funktion nur zum Debuggen gedacht ist. Es ist ein wenig irreführend für eine Funktion namens printGraph, den Kantenvektor trotzdem zu verändern.

Verwandte Themen