排序仿函數 出現 std::priority_queue::push() 的 invalid operator < 異常

首先看一段代碼: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.

相關文章
相關標籤/搜索