2009-10-09 38 views
13

Tôi đang gặp rất nhiều sự cố khi nhận hàng đợi ưu tiên của mình để nhận ra thông số cần sắp xếp. Tôi đã quá tải các nhà điều hành ít hơn trong lớp tùy chỉnh của tôi, nhưng nó dường như không sử dụng nó. Dưới đây là các mã có liên quan:Hàng đợi ưu tiên STL trên lớp tùy chỉnh

Node.h

class Node 
{ 
public: 
    Node(...); 
    ~Node(); 
    bool operator<(Node &aNode); 
... 
} 

Node.cpp

#include "Node.h" 
bool Node::operator<(Node &aNode) 
{ 
    return (this->getTotalCost() < aNode.getTotalCost()); 
} 

getTotalCost() trả về một int

main.cpp

priority_queue<Node*, vector<Node*>,less<vector<Node*>::value_type> > nodesToCheck; 

gì Tôi đang thiếu và/hoặc làm sai?

+0

Bạn phải ở AI Chai class :) http://stackoverflow.com/questions/1517854/priorityqueue-comparison-for-pointers – Polaris878

+0

Kỹ năng thám tử tốt;) – bmalicoat

Trả lời

21

less<vector<Node*>::value_type> Phương tiện mà so sánh của bạn so sánh con trỏ với nhau, có nghĩa là vector của bạn sẽ được sắp xếp theo cách bố trí trong bộ nhớ của các nút.

Bạn muốn làm một cái gì đó như thế này:

#include <functional> 
struct DereferenceCompareNode : public std::binary_function<Node*, Node*, bool> 
{ 
    bool operator()(const Node* lhs, const Node* rhs) const 
    { 
     return lhs->getTotalCost() < rhs->getTotalCost(); 
    } 
}; 

// later... 
priority_queue<Node*, vector<Node*>, DereferenceCompareNode> nodesToCheck; 

Lưu ý rằng bạn cần phải const-đúng định nghĩa của bạn về totalCost.

EDIT: Bây giờ C++ 11 là ở đây, bạn không cần phải kế thừa từ std :: binary_function nữa (có nghĩa là bạn không cần phải #include chức năng)

+1

Hết sức tò mò: tại sao xác định cấu trúc với toán tử() thay vì chỉ là một hàm? –

+3

Bạn phải làm vậy. Bạn không thể chuyên các mẫu có chức năng, chỉ các loại (không bao gồm các trường hợp cụ thể). Các đối tượng hàm là một phần rất quan trọng trong lập trình STL. Một cuốn sách tuyệt vời để đọc được là * STL * hiệu quả của Scott Meyer *.Nó giải thích tất cả về STL và cách tốt nhất để tận dụng nó. – rlbond

+0

Ngoài ra, tôi nên chỉ ra rằng 'std :: less ' cũng là một đối tượng hàm (tức là, một cấu trúc với 'toán tử()') – rlbond

14

Bạn cần thực hiện tham số const, bởi vì hiện tại bạn đang cung cấp tham chiếu không phải trả phí, có nghĩa là bạn có thể sửa đổi đối tượng mà bạn đang so sánh. (Mà bạn không, và có lẽ không nên).

Bạn không phải là chính xác. operator< của bạn không làm thay đổi đến Node, do đó chức năng nên được const:

bool operator<(const Node &aNode) const; 

Sau đó, nếu bạn gặp khó khăn khi gọi getTotalCost() chức năng, nó có khả năng rằng nó không phải là const là tốt. Đánh dấu nó là const nếu chưa:

int getTotalCost(void) const; 

Mã của bạn bây giờ là (nhiều hơn) chính xác.

Trên một mặt lưu ý, các nhà khai thác nhị phân thường được thực hiện bên ngoài lớp:

class Node 
{ 
public: 
    // ... 

    int getTotalCost(void) const; 

    // ... 
}; 

bool operator<(const Node& lhs, const Node& rhs) 
{ 
    return lhs.getTotalCost() < rhs.getTotalCost(); 
} 
+1

+1: giao diện tối thiểu là những điều tốt –

+0

Thực ra, tôi phải không đồng ý với định nghĩa của 'operator <' bên ngoài lớp trong một số trường hợp. Nếu nó rõ ràng cắt những gì nó phải làm, tôi không nghĩ rằng nó thực sự là một việc lớn để xác định nó như là một thành viên. Plus nó cho phép sử dụng Boost.Operators. – rlbond

Các vấn đề liên quan