zoukankan      html  css  js  c++  java
  • 排序仿函数 出现 std::priority_queue::push() 的 invalid operator < 异常

    首先看一段代码:

    #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;
    };

    结果输出 最大值优先的 列表:

    但如果将  比较器改成:

    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 版本):

    出现 invalid operator <

    原因在于 最后两种的比较器 结果为 true 时是不对称的, 即 如果 A < B 那么对称的应该是 B < A; 即如果 cmp( A, B) 返回true, 那么应该 cmp( B, A) 返回 false, 但不应该

    cmp( A, B) = true

    cmp( B, A) = true

    出现 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.

  • 相关阅读:
    使用JDBC连接MySql时出现:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration
    Mysql Lost connection to MySQL server at ‘reading initial communication packet', system error: 0
    mysql-基本命令
    C# 监听值的变化
    DataGrid样式
    C# 获取当前日期时间
    C# 中生成随机数
    递归和迭代
    PHP 时间转几分几秒
    PHP 根据整数ID,生成唯一字符串
  • 原文地址:https://www.cnblogs.com/Wilson-Loo/p/3375325.html
Copyright © 2011-2022 走看看