2012-11-07 44 views
5

Tôi biết rằng có những chủ đề tương tự nhưng sau một giờ cố gắng buộc chương trình của tôi hoạt động, tôi quyết định yêu cầu trợ giúp. Trước hết. Tôi đã nghĩ rằng tôi biết c + + khá tốt kể từ khi tôi đã thử một cái gì đó rất đơn giản trong PHP (ngôn ngữ lập trình mà tôi biết tốt nhất) nhưng rất phức tạp trong c + + (ít nhất là rất phức tạp đối với tôi). Vì vậy, tôi muốn tạo priority_queue của các con trỏ của struct. Rõ ràng là tôi cần tạo ra hàm so sánh của riêng mình. Vì vậy, tôi đã cố gắng mã này:Hàng đợi ưu tiên của các con trỏ của cấu trúc

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

Và khi tôi đã cố gắng để biên dịch chương trình của tôi, tôi đã kết thúc với lỗi biên dịch:

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

Bạn có thể giải thích cho tôi những gì tôi đang làm sai và giải thích cho tôi như thế nào tất cả công cụ này với cấu trúc so sánh công trình (hoặc cho tôi một hướng dẫn tốt/bài viết mà giải thích rằng ngay từ đầu)

EDIT:

Tôi đã thay đổi mã của tôi như thế này:

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

Và bây giờ tôi nhận được msg lỗi này:

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’ 

vấn đề là gì? Có lẽ tôi nên sử dụng bản sao của cấu trúc thay vì trỏ đến cấu trúc?

EDIT2

Mã này không tạo ra bất kỳ lỗi biên dịch:

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

ý tưởng Vì vậy @Angew có vẻ là sai.

EDIT3: Đây là mã cuối cùng của tôi. Nó không chỉ biên dịch mà không có lỗi mà còn làm chính xác những gì tôi muốn. Cảm ơn bạn rất nhiều @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

Bạn nói đúng, tôi đã đọc sai tài liệu về priority_queue. Tôi đã chỉnh sửa câu trả lời của mình. – Angew

Trả lời

6

Có là nhiều vấn đề ở đây.

Khi bạn xác định toán tử bên trong một lớp, nó sẽ tự động lấy tham số của loại lớp làm đối số đầu tiên của nó và bạn không được tạo tham số cho nó. Vì vậy, bạn có giữ các nhà điều hành trong lớp, như vậy:

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

hoặc tuyên bố các nhà điều hành như miễn phí-đứng:

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

Thứ hai, priority_queue cửa hàng con trỏ của bạn để MI, không trường hợp của MI, do đó, các nhà điều hành sẽ không được gọi là anyway. Bạn phải cung cấp một so sánh khi xác định hàng đợi ưu tiên, như thế này (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; 
    //... 
} 

thứ ba chỉ là một điều phong cách: Tôi muốn đề nghị bạn đặt tên cho lớp trực tiếp miasto chứ không phải làm cho nó chỉ là một typedef . Nó tự nhiên hơn trong C++.

3

Các lỗi, nếu bạn đọc nó một lần nữa, sẽ cho bạn biết chính xác những gì là sai: Đó là MI::operator< chức năng nên chỉ mất một đối số thay vì hai.

Nếu bạn có operator<trong lớp (như bạn làm) thì hàm này chỉ nhận một đối số và đó là đối tượng khác để so sánh this với. Nếu bạn tạo operator< làm miễn phí đứng chức năng (tức là không phải là một phần của lớp) thì phải có hai đối số.

-1

Sử dụng từ khoá friend để đưa các nhà điều hành < trong phạm vi toàn cầu

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

Không cần "bạn bè" ở đây. – juanchopanza

+0

1. Đây là cách dễ nhất để khắc phục sự cố. 2. Ký pháp này cho phép kết hợp toán tử <'vào một giao diện duy nhất, nghĩa là, được ưu tiên – pogorskiy

+0

Đối với tôi, nó giống như một sự lạm dụng của 'người bạn'. Ngoài ra, tôi sẽ xem xét chức năng không phải thành viên không phải là thành viên của một giao diện. Một số đọc thú vị [ở đây] (http://www.gotw.ca/publications/mill02.htm). PS Tôi đã không downvote BTW. – juanchopanza

1

toán tử so sánh của bạn là một hàm thành viên, vì vậy nó chỉ nên dùng một tham số, cho theRHS:

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

Một tùy chọn là tuyên bố nó là một chức năng không phải là thành viên:

struct MI {}; 

bool operator<(const MI& a, const MI& b) { 
     return a.koszt > b.koszt; 
} 
Các vấn đề liên quan