[英]C++ priority queue in ascending order by specific method for unique pointers to objects
我有一個名為Foo
的類,每個Foo
對象都有一個名為yVal
的方法。 我想要的是按Foo.yVal()
升序排列的Foo
對象的優先級隊列
我將Foo
的 operator> 和 operator< 重載為:
bool operator> (const Foo &f){
return yVal() > f.yVal();
}
bool operator< (const Foo &f){
return yVal() < f.yVal();
}
所以我有以下代碼:
priority_queue<unique_ptr<Foo>, vector<unique_ptr<Foo>>, greater<unique_ptr<Foo>> > Queue;
但這並不是按Foo.yVal()
升序對優先級隊列進行排序。 相反,它只是以某種未知的隨機順序對它們進行排序。 我在 operator> 和 operator< 中放置了一個 cout 語句,它們甚至沒有被調用。 所以我嘗試用 lambda 來代替:
auto cmp = [](Foo left, Foo right) {return left.xVal() > right.xVal();};
priority_queue<unique_ptr<Foo>, vector<unique_ptr<Foo>>, decltype(cmp) > Queue(cmp);
但這給了我“非靜態數據成員聲明為自動”錯誤的錯誤。
理想情況下,我希望通過更大的<> 和運算符重載來實現這一點。 如果不是,請告訴我我在使用 lambda 時做錯了什么(對 lambda 不太熟悉,如果可能的話希望避免使用它們)。
我也嘗試過使用函子,但同樣,函子上的 auto 給了我相同的“非靜態數據成員聲明為 auto”錯誤。
你得到了未知的隨機順序,因為當你有greater<T>
會執行以下操作
// pseudocode
cmp(T lhs, T rhs) {
return lhs > rhs;
}
你的代碼中的T
是什么? T
是unique_ptr<Foo>
,C++ 庫中有operator>(unique_ptr<>,unique_ptr<>)
嗎? 是的, 在這里看到,並且這個運算符在比較時使用unique_ptr::get
方法:
// Psuedocode when greater used:
cmp (unique_ptr<Foo>& lhs, unique_ptr<Foo>& rhs)
{
lhs.get () > rhs.get()
}
unique_ptr::get
返回什么? 它返回指向Foo
指針,因此您正在比較指向Foo
實例的指針。 結果難以預料。 代碼編譯並執行,但它沒有按照您的預期執行。
如何修復您的 lambda:
您的隊列中存儲了哪些對象? Foo
還是unique_ptr<Foo>
? 您正在存儲unique_ptr<Foo>
因此您的 lambda 參數應聲明為采用這種類型。
auto cmp = [](const unique_ptr<Foo>& left, const unique_ptr<Foo>& right)
{ ^^^^^^^^^^^^^^^^
return left->yVal() > right->yVal();
}; ^^
priority_queue<unique_ptr<Foo>, vector<unique_ptr<Foo>>, decltype(cmp) > Queue(cmp);
因為unique_ptr
實例不能被復制,所以你必須通過引用傳遞它們。 還可以使用->
運算符訪問yVal
方法。
編輯:帶有函數對象的版本。
// comparator as function object with overloaded operator()
struct Cmp {
bool operator()(const std::unique_ptr<Foo>& left, const std::unique_ptr<Foo>& right) const {
return left->xVal() > right->xVal();
}
};
class YourClass {
public:
std::priority_queue<std::unique_ptr<Foo>, std::vector<std::unique_ptr<Foo>>, Cmp> Queue;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.