首先看一段代碼:node
#include <queue> #include <deque> #include <iostream> int main() { struct node { int value; }; struct cmp { bool operator()( const node& a, const node& b ) { return a.value < b.value; } }; std::priority_queue<node, std::deque<node>, cmp > pri_queue; node n1 = {22}; node n2 = {11}; node n3 = {33}; node n4 = {11}; pri_queue.push( n1); pri_queue.push( n2); pri_queue.push( n3); pri_queue.push( n4); while( ! pri_queue.empty() ) { node n = pri_queue.top(); pri_queue.pop(); std::cout << n.value << std::endl; } system( "PAUSE"); return 0; };
結果輸出 最大值優先的 列表:
ios
但若是將 比較器改爲:less
struct cmp { bool operator()( const node& a, const node& b ) { return a.value <= b.value; } }; 或者 struct cmp { bool operator()( const node& a, const node& b ) { return true; } };
都會運行異常(當前是 debug 版本):spa
出現 invalid operator <debug
緣由在於 最後兩種的比較器 結果爲 true 時是不對稱的, 即 若是 A < B 那麼對稱的應該是 B < A; 即若是 cmp( A, B) 返回true, 那麼應該 cmp( B, A) 返回 false, 但不該該 設計
cmp( A, B) = truecode
cmp( B, A) = trueblog
出現 invalid operator <, 是由於 std::priority_queue 默認使用 less 比較, 若是 A 小於 B 爲真, 那麼 B 小於 A 就不該該爲真, 排序
這裏考察 開發
node n2 = {11}; node n4 = {11};
當 調用 push( n4) 時, 必然的要進行排序, 已實現 priority_queue 機制,
檢查第一個 cmp 比較器:
struct cmp { bool operator()( const node& a, const node& b ) { return a.value < b.value; } };
cmp( n2, n4 ) = false;
cmp( n4, n2 ) = false;
不會同時爲 true , 知足 "結果爲true 對稱" 條件, 由於這裏兩個值都爲 false.
第二個比較器:
struct cmp { bool operator()( const node& a, const node& b ) { return a.value <= b.value; } };
cmp( n2, n4 ) = true;
cmp( n4, n2 ) = true;
同時爲 true了, 不對稱, 因此在debug版本運行是報錯.
第三個比較器 就更加 不對稱了:
struct cmp { bool operator()( const node& a, const node& b ) { return true } };
cmp( n2, n4 ) = true;
cmp( n4, n2 ) = true;
其實我並無查看過 std::priority_queue的 排序源碼, 只是綜合其餘開發人員的意見有: 當比較器struct cmp 進行比較獲取 true 值時, 預期爲獲取到理想值(較大者?較小者), 再進行後續操做, 可是在 debug 版本時, 會同時檢測 兩個 比較元素的 不一樣 lhs 和 rhs 順序會不會同時爲 true, 是的運行報錯, 但這是基於什麼嚴格的 設計理念, 我暫時還未能瞭解到.
本篇總結爲, 在設計 比較器時, 要確保 兩個元素 n2 和 n4 的 lhs / rhs 順序 不會同時 爲 true.