2012-11-07 24 views
5

Wiem, że są podobne wątki, ale po spędzeniu godziny próbując zmusić program do działania, postanowiłem poprosić o pomoc. Przede wszystkim. Myślałem, że znam C++ całkiem dobrze, odkąd spróbowałem czegoś, co jest bardzo proste w PHP (języku programowania, który znam najlepiej), ale bardzo skompleksowanym w C++ (co najmniej bardzo skomplikowanym dla mnie). Dlatego chcę utworzyć priority_queue dla wskaźników struct. To oczywiste, że muszę stworzyć własną funkcję porównywania. Więc próbowałem ten kod:Kolejka priorytetowa wskaźników struktury

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

A kiedy próbowałem skompilować mój program skończyło się błędem kompilacji:

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

Czy możesz mi wyjaśnić, co robię źle i wyjaśnić mi jak to wszystko to rzeczy z kodowanym porównać dzieła (lub dać mi dobry tutorial/artykuł, który wyjaśnia, że ​​od początku)

EDIT:

zmieniłem kod do tego:

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

I teraz otrzymuję ten błąd błędzie:

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’ 

Na czym polega problem? Może powinienem użyć kopii struktur zamiast wskazówek do struktur?

EDIT2

Kod ten nie wywołuje żadnych błędów kompilacji:

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

Więc @Angew pomysł wydaje się być błędne.

EDIT3: To jest mój ostateczny kod. Nie tylko kompiluje bez błędów, ale także robi dokładnie to, co chcę. Dziękuję bardzo @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

Masz rację, błędnie przeczytałem dokumentację priority_queue. Edytowałem swoją odpowiedź. – Angew

Odpowiedz

6

tutaj jest wiele problemów.

Po zdefiniowaniu operatora wewnątrz klasy, automatycznie przyjmuje on parametr typu klasy jako jego pierwszy argument i nie można utworzyć dla niego parametru. Więc albo zachować operatora w klasie, tak jak poniżej:

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

lub zadeklarować operatora jako wolnostojące:

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

drugie, swoje priority_queue przechowuje wskaźniki do MI nie przypadki MI, więc operator i tak nie zostanie wywołany. Musisz podać komparator przy definiowaniu kolejkę priorytetową, jak to (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; 
    //... 
} 

trzeci jest właśnie coś w stylu: ja proponuję nazwać klasę bezpośrednio miasto aniżeli czyni to tylko typedef . Jest bardziej naturalny w C++.

3

Błąd, jeśli ją ponownie przeczytać, mówi dokładnie to, co się stało: że funkcja MI::operator< powinien wziąć tylko jeden argument, zamiast dwóch.

Jeśli masz operator<w klasy (jak to zrobić), to funkcja przyjmuje tylko jeden argument, a to jest inny obiekt porównać this z. Jeśli utworzysz operator< jako niezależną funkcję (tj. Nie będącą częścią klasy), wówczas musi ona przyjąć dwa argumenty.

-1

Zastosowanie przyjaciel kluczowe aby umieścić operator < w zasięgu globalnym

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

Nie ma tu potrzeby "przyjaciela". – juanchopanza

+0

1. Jest to najprostszy sposób na rozwiązanie problemu. 2. Ta notacja pozwala połączyć "operator <" w jeden interfejs, czyli jest preferowany – pogorskiy

+0

Dla mnie wygląda to na nadużycie "przyjaciela". Ponadto uważałbym, że nie-przyjacielska funkcja niebędąca członkiem jest częścią interfejsu. Ciekawe lektury [tutaj] (http://www.gotw.ca/publications/mill02.htm). PS Nie złożyłem przysięgi BTW. – juanchopanza

1

Twój operator porównania jest funkcją członkiem, więc powinno to potrwać tylko jeden parametr, na theRHS:

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

Another opcją jest zadeklarowanie jej jako funkcji niezrzeszonej:

struct MI {}; 

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