2012-11-07 12 views
5

Ich weiß, dass es ähnliche Threads gibt, aber nachdem ich eine Stunde lang versucht habe, mein Programm zum Laufen zu bringen, habe ich beschlossen, um Hilfe zu bitten. Zunächst einmal. Ich habe gedacht, dass ich C++ ziemlich gut kenne, da ich etwas versucht habe, das in PHP sehr einfach ist (Programmiersprache, die ich am besten kenne), aber sehr komplex in C++ (zumindest sehr komplex für mich). Also möchte ich priority_queue der Zeiger der Struktur erstellen. Es ist offensichtlich, dass ich meine eigene Vergleichsfunktion erstellen muss. Also habe ich versucht, diesen Code:Priority Queue von Structs Zeigern

#include <iostream> 
#include <list> 
#include <queue> 

using namespace std; 

typedef struct MI 
{ 
    int nr; 
    int koszt; 
    bool operator<(const MI& a, const MI& b) { 
     return a.koszt > b.koszt; 
} 
} miasto, *miasto_wsk; 

int main() 
{ 
    priority_queue<miasto_wsk> q; 
    miasto_wsk mi; 
    mi = new miasto; 
    mi->nr = 1; 
    mi->koszt = 2; 
    q.push(mi); 
} 

Und als ich versuchte, mein Programm zu kompilieren ich mit Kompilierungsfehler endete:

test.cpp:11:44: error: ‘bool MI::operator<(const MI&, const MI&)’ must take exactly one argument 

Können Sie mir erklären, was ich falsch mache und mir erklären, wie alle dieses Zeug mit structs vergleichen Werke (oder geben Sie mir ein gutes Tutorial/Artikel, der das von Anfang an erklärt)

EDIT:

änderte ich meinen Code dazu:

#include <iostream> 
#include <list> 
#include <queue> 

using namespace std; 

typedef struct miasto 
{ 
    int nr; 
    int koszt; 
} *miasto_wsk; 

bool myComparator(miasto_wsk arg1, miasto_wsk arg2) { 
     return arg1->koszt < arg2->koszt; //calls your operator 
} 

int main() 
{ 
    priority_queue<miasto_wsk, vector<miasto_wsk>, myComparator> q; 
    miasto_wsk mi; 
    mi = new miasto; 
    mi->nr = 1; 
    mi->koszt = 2; 
    q.push(mi); 
} 

Und jetzt diesen Fehler msg ich immer:

test.cpp: In function ‘int main()’: 
test.cpp:19:64: error: type/value mismatch at argument 3 in template parameter list for ‘template<class _Tp, class _Sequence, class _Compare> class std::priority_queue’ 
test.cpp:19:64: error: expected a type, got ‘myComparator’ 
test.cpp:19:67: error: invalid type in declaration before ‘;’ token 
test.cpp:24:7: error: request for member ‘push’ in ‘q’, which is of non-class type ‘int’ 

Was ist das Problem? Vielleicht sollte ich Kopien von Strukturen statt Zeiger auf Strukturen verwenden?

EDIT2

Dieser Code keine Kompilierungsfehlern produziert:

#include <iostream> 
#include <list> 
#include <queue> 

using namespace std; 

typedef struct miasto 
{ 
    int nr; 
    int koszt; 
    bool operator< (const miasto& rhs) 
    { 
    koszt > rhs.koszt; 
    } 
} *miasto_wsk; 

int main() 
{ 
    priority_queue<miasto_wsk> q; 
    miasto_wsk mi; 
    mi = new miasto; 
    mi->nr = 1; 
    mi->koszt = 22; 
    q.push(mi); 
} 

So @Angew Idee scheint falsch zu sein.

EDIT3: Dies ist mein endgültiger Code. Es kompiliert nicht nur fehlerfrei, sondern macht genau das, was ich will. Vielen Dank @Angew

#include <iostream> 
#include <list> 
#include <queue> 

using namespace std; 

typedef struct miasto 
{ 
    int nr; 
    int koszt; 
} *miasto_wsk; 

struct MyComparator { 
    bool operator() (miasto_wsk arg1, miasto_wsk arg2) { 
     return arg1->koszt > arg2->koszt; //calls your operator 
    } 
}; 


int main() 
{ 
    //priority_queue<miasto_wsk, vector<miasto_wsk>, myComparator> q; 
    priority_queue<miasto_wsk, vector<miasto_wsk>, MyComparator> q; 
    miasto_wsk mi; 
    mi = new miasto; 
    mi->nr = 1; 
    mi->koszt = 22; 
    q.push(mi); 
    miasto_wsk mi1; 
    mi1 = new miasto; 
    mi1->nr = 2; 
    mi1->koszt = 50; 
    q.push(mi1); 
    miasto_wsk mi2; 
    mi2 = new miasto; 
    mi2->nr = 3; 
    mi2->koszt = 1; 
    q.push(mi2); 

    cout << q.top()->koszt << endl; 
    q.pop(); 
    cout << q.top()->koszt << endl; 
    q.pop(); 
    cout << q.top()->koszt << endl; 
    q.pop(); 
} 
+0

Sie haben Recht, ich habe die Dokumente auf priority_queue falsch gelesen. Ich habe meine Antwort bearbeitet. – Angew

Antwort

6

Dort sind mehrere Probleme hier.

Wenn Sie einen Operator innerhalb einer Klasse definieren, wird automatisch ein Parameter des Klassentyps als erstes Argument verwendet, und Sie dürfen keinen Parameter dafür erstellen. Also entweder Sie den Operator in der Klasse halten, etwa so:

struct MI { 
    bool operator< (const MI&); 
}; 

oder den Betreiber als freistehende erklären:

struct MI { 
    //... 
}; 
bool operator< (const MI&, const MI&); 

Zweitens Ihre priority_queue speichert Zeiger auf MI, keine Instanzen von MI, Der Operator wird also nicht angerufen. Sie müssen einen Komparator vorzusehen, wenn die Prioritätswarteschlange zu definieren, wie diese (EDITED):

struct MyComparator { 
    bool operator() (miasto_wsk arg1, miasto_wsk arg2) { 
    return *arg1 < *arg2; //calls your operator 
    } 
}; 

int main() { 
    priority_queue<miasto_wsk, vector<miasto_wsk>, MyComparator> q; 
    //... 
} 

Dritte ist nur eine Art Sache: Ich würde Sie die Klasse direkt miasto eher vorschlagen nennen, als es macht nur einen typedef . In C++ ist es natürlicher.

3

Der Fehler, wenn Sie es noch einmal lesen, sagt Ihnen genau, was los ist: Dass die MI::operator< Funktion von zwei statt nur ein Argument nehmen.

Wenn Sie operator<in die Klasse haben (wie Sie tun), dann die Funktion nur ein Argument, und das ist das andere Objekt vergleichen this mit. Wenn Sie operator< als freistehende-Funktion erstellen (d. H. Nicht Teil der Klasse), müssen zwei Argumente verwendet werden.

-1

Verwenden Freund Stichwort den Operator < im globalen Bereich zu setzen

typedef struct MI 
{ 
    int nr; 
    int koszt; 
    friend bool operator<(const MI& a, const MI& b) 
    { 
     return a.koszt > b.koszt; 
    } 
} miasto, *miasto_wsk; 
+1

Keine Notwendigkeit für "Freund" hier. – juanchopanza

+0

1. Dies ist der einfachste Weg, um das Problem zu beheben. 2. Diese Notation ermöglicht es, den 'Operator <' zu einer einzigen Schnittstelle zu kombinieren, das heißt, ist die bevorzugte – pogorskiy

+0

Für mich sieht es aus wie ein Missbrauch von 'Freund'. Außerdem würde ich die non-friend non-member-Funktion als Teil der Schnittstelle betrachten. Einige interessante Lektüre [hier] (http://www.gotw.ca/publications/mill02.htm). PS Ich habe BTW nicht runtergestimmt. – juanchopanza

1

Ihr Vergleichsoperator ist eine Member-Funktion, so dass es nur einen Parameter übernehmen sollte, für theRHS:

bool operator<(const MI& rhs) { 
     koszt > rhs.koszt; 
} 

Another Die Option besteht darin, sie als Nichtmitgliedsfunktion zu deklarieren:

struct MI {}; 

bool operator<(const MI& a, const MI& b) { 
     return a.koszt > b.koszt; 
}