zoukankan      html  css  js  c++  java
  • 从优先队列中重载小于号谈起

    看一个问题

    看下面这段代码

    // cpp
    struct node {
        int a, b;
        bool operator< (const node& x) {
            return a > x.a;
        }
    };
    int main()
    {
        priority_queue<node> pq;
        pq.push(node{1, 2});
        return 0;
    }
    

    代码意图声明一个结构体并重载小于号,以使用优先队列维护

    但是过不了编译,部分报错信息如下

    报错信息

    追踪

    看一下 /usr/include/c++/6/bits/stl_function.h:386:20 指向的代码

    // cpp
    template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
        _GLIBCXX14_CONSTEXPR
        bool
        operator()(const _Tp& __x, const _Tp& __y) const
        { return __x < __y; }
    };
    

    可以看到 less() 这个函数对象 (function object) 重载了 () 运算符,接收两个 const 类型的参数

    而在 cpp 里面,只有 const 成员函数才能够被 const 对象调用

    这是编译器为了保证成员函数不会修改 const 对象的成员变量,所做出的强制要求

    解决

    解决方法很简单,把重载运算符的函数声明为 const 即可

    // cpp
    struct node {
        int a, b;
        bool operator< (const node& x) const {
            return a > x.a;
        }
    };
    int main()
    {
        priority_queue<node> pq;
        pq.push(node{1, 2});
        return 0;
    }
    

    为优先队列重载小于号的四种办法

    给定结构体

    // cpp
    struct node {
        int a, b;
    };
    
    int main()
    {
        priority_queue<node> pq;
        pq.push(node{1, 2});
        return 0;
    }
    

    为它重载小于号,以支持优先队列来维护它

    在类内声明成员函数

    声明为 const 的成员函数,输入参数也得是 const

    // cpp
    struct node {
        int a, b;
        bool operator< (const node& x) const
        {
            return a > x.a;
        }
    };
    int main()
    {
        priority_queue<node> pq;
        pq.push(node{1, 2});
        pq.push(node{2, 3});
        cout << pq.top() << endl; // 输出: 1 2
        return 0;
    }
    

    考虑一个简单的声明

    const node A{1, 2};
    const node B{3, 4};
    

    那么有如下等价的语句

    (A < B) <=> A.operator< (B)
    

    因此一切变得可以理解起来了

    • 由于是 const 对象的比较,所以声明为 const member function
    • 由于传入的参数也是 const 对象,所以成员函数的参数也要设置为 const,以扩大接受对象的范围

    在类内声明为友元函数

    // cpp
    struct node {
        int a, b;
        friend bool operator< (const node& x, const node& y)
        {
            return x.a > y.a;
        }
    };
    
    int main()
    {
        priority_queue<node> pq;
        pq.push(node{1, 2});
        pq.push(node{2, 3});
        cout << pq.top() << endl; // 输出: 1 2
        return 0;
    }
    

    友元函数虽然定义在类内,但是不是类的成员函数,只是具有类成员变量的访问权

    在类外重载小于号

    // cpp
    struct node {
        int a, b;
    };
    
    bool operator< (const node& x, const node& y)
    {
        return x.a > y.a;
    }
    
    int main()
    {
        priority_queue<node> pq;
        pq.push(node{1, 2});
        pq.push(node{2, 3});
        cout << pq.top() << endl; // 输出: 1 2
        return 0;
    }
    

    声明新的函数对象

    // cpp
    struct node {
        int a, b;
        friend ostream& operator<< (ostream& out, const node& x) {
            out << x.a << ' ' << x.b;
        }
    };
    struct cmp {
        bool operator() (const node& x, const node& y) {
            return x.a > y.a;
        }
    };
    
    int main()
    {
        priority_queue<node, vector<node>, cmp> pq;
        pq.push(node{1, 2});
        pq.push(node{2, 3});
        cout << pq.top() << endl; // 输出: 1 2
        return 0;
    }
    
  • 相关阅读:
    tyvj1117 拯救ice-cream
    codevs3410 别墅房间
    codevs1099 字串变换
    codevs1226 倒水问题
    codevs2449 骑士精神
    codevs1225 八数码难题
    Wikioi 3776 生活大爆炸版石头剪子布
    codevs1197 Vigenère密码
    枚举 + exgcd
    C++ 排序引用的优化
  • 原文地址:https://www.cnblogs.com/ChenyangXu/p/15583108.html
Copyright © 2011-2022 走看看