2012-11-07 14 views
5

So che ci sono thread simili ma dopo aver passato un'ora cercando di forzare il mio programma a funzionare, ho deciso di chiedere aiuto. Prima di tutto. Ho pensato di conoscere bene il C++ da quando ho provato qualcosa che è molto semplice in PHP (linguaggio di programmazione che conosco meglio) ma molto complesso in C++ (almeno per me molto complesso). Quindi voglio creare priority_queue dei puntatori di struct. È ovvio che ho bisogno di creare la mia funzione di confronto. Così ho provato questo codice:Coda prioritaria dei puntatori di struct

#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); 
} 

E quando ho provato a compilare il mio programma ho finito con errore di compilazione:

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

Mi potete spiegare che cosa sto facendo male e mi spiegare come tutto questa roba con le strutture confrontare opere (o mi dia un buon tutorial/articolo che spiega che fin dall'inizio)

EDIT:

ho cambiato il mio codice a questo:

#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); 
} 

Ed ora questo errore msg:

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’ 

Qual è il problema? Forse dovrei usare le copie delle strutture invece dei puntatori alle strutture?

EDIT2

Questo codice non produce errori di compilazione:

#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); 
} 

idea Così @Angew sembra essere sbagliato.

EDIT3: Questo è il mio codice finale. Non solo compila senza errori ma fa anche esattamente quello che voglio. Grazie mille @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

Hai ragione, ho letto male i documenti su priority_queue. Ho modificato la mia risposta. – Angew

risposta

6

Là sono più problemi qui.

Quando si definisce un operatore in una classe, esso assume automaticamente un parametro del tipo di classe come primo argomento e non è necessario creare un parametro per esso. Così si sia mantenere l'operatore nella classe, in questo modo:

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

o dichiarare l'operatore come free-standing:

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

In secondo luogo, i tuoi priority_queue memorizza puntatori a MI, non le istanze di MI, quindi l'operatore non verrà chiamato comunque. È necessario fornire un comparatore quando si definisce la coda di priorità, in questo modo (A CURA ):

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; 
    //... 
} 

Terzo è solo una cosa stile: Io suggerirei è il nome della classe direttamente miasto piuttosto che fare solo un typedef . È più naturale in C++.

3

L'errore, se lo si legge ancora una volta, ti dice esattamente ciò che è sbagliato: che la funzione MI::operator< dovrebbe richiedere solo un argomento invece di due.

Se hai operator<nel classe (come si fa), allora la funzione prende un solo argomento e che è l'altro oggetto per confrontare this con. Se crei operator< come una funzione libera autonoma (ad esempio non parte della classe), allora devi prendere due argomenti.

-1

Usa amico parola chiave per mettere l'operatore < nell'ambito globale

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

Non c'è bisogno di 'amico' qui. – juanchopanza

+0

1. Questo è il modo più semplice per risolvere il problema. 2. Questa notazione consente di combinare l'operatore <'in una singola interfaccia, ovvero, è il preferito – pogorskiy

+0

Per me sembra un abuso di 'amico'. Inoltre, considererei la funzione non membro non amico come parte dell'interfaccia. Qualche lettura interessante [qui] (http://www.gotw.ca/publications/mill02.htm). PS Non ho downvotato BTW. – juanchopanza

1

Il vostro operatore di confronto è una funzione membro, quindi dovrebbe prendere un solo parametro, per theRHS:

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

altro l'opzione è dichiararlo come una funzione non membro:

struct MI {}; 

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