[英]Sorted set without a strict weak ordering
我有以下問題:考慮這種(簡化的)結構:
struct Task {
int priority;
std::string description;
// Some other fields
};
現在,我要擁有一組所有任務並對其進行一些處理。 因此,我有一個相等運算符,該運算符檢查每個元素是否相等。
bool isEqual(const Task& lhs, const Task& rhs) {
return lhs.priority == rhs.priority &&
lhs.description == rhs.description &&
// Some other fields
;
}
為此,我使用了std :: unordered_set,效果很好。
但是現在我希望這些任務按集合中的優先級排序(以獲得最高優先級的任務)。 顯然,這對於std :: unordered_set是不可能的,因此我嘗試了使用以下較少運算符的std :: set:
bool lessTask(const Task& lhs, const Task& rhs) {
return lhs.priority < rhs.priority;
}
但這意味着嚴格的弱排序,當優先級相等時,兩個任務是相等的,而我不希望這樣做(我想維護我的isEqual方法以進行相等性檢查)。
什么是完成一組任務的最佳方法,在該方法中,我可以非常快速地插入元素並且沒有重復的條目(由isEqual函數定義),但是能夠真正快速地檢索優先級最高的任務?
我沒有綁定到任何特定的STL容器,但不想使用任何第三方庫(甚至不使用boost)。
在地圖上放置元素時,通常需要將該類的所有成員添加到less
。 否則它將無法正常工作。 當我不得不創建一個包含約15種不同的,不斷變化的類的系統時,這是一個巨大的挑戰,而那時我真的開始錯過了編譯時反射。
另外,您可以使用優先級隊列 ( std::make_heap
)來代替映射。 優先堆不關心相等性,它將首先為您提供具有最高優先級的任務。
首先寫get_tie
:
// auto or decltype(auto)
auto get_tie(const Task& task) {
return std::tie(lhs.priority, lhs.description, /* some other fields */ );
}
在C ++ 11中,您必須使用->decltype
尾隨返回類型來重復主體,或者使用宏來避免重復:
#define RETURNS(...) decltype(__VA_ARGS__) { return __VA_ARGS__; }
auto get_tie(const Task& task)->
RETURNS( std::tie(lhs.priority, lhs.description, /* some other fields */ ) )
一旦我們有了一個簡單的get_tie
,您的問題就消失了。
bool isEqual( Task const& lhs, Task const& rhs ) {
return get_tie(lhs)==get_tie(rhs);
}
bool isLess( Task const& lhs, Task const& rhs ) {
return get_tie(lhs) < get_tie(rhs);
}
只需將isLess
傳遞給std::set
,或使用isLess
構建一個std::vector
和std::sort
isLess
。
現在,如果你的比較並沒有真正在原始工作tie
引用,則可能必須更換get_tie
與更復雜的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.