std::sort 为啥不需要 decltype,而 priority_queue 有时却需要,自定义比较大小

std::sort 为啥不需要 decltype,而 priority_queue 有时却需要?

我们来彻底讲清楚它们底层的原理和差别,并帮你记住什么时候用 decltype


✅ 先说现象:你写的两种用法

std::sort 示例:

bool cmp(const pair<int, int>& a, const pair<int, int>& b) {
    return a.first < b.first;
}
sort(v.begin(), v.end(), cmp);  // 没有用 decltype

priority_queue 示例:

bool cmp(const pair<int, int>& a, const pair<int, int>& b) {
    return a.first > b.first;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);  // 用了 decltype

🧠 根本区别在于:函数 vs 模板参数

🟦 std::sort 的第三个参数是一个函数对象(Function Pointer 或 Lambda),是运行时传参

你传的是一个函数(或者函数指针):

sort(..., cmp);  // cmp 是个函数,函数指针类型自动推导

它不需要你提前告诉它类型。


🟥 priority_queue 的比较器是模板参数,是编译期类型确定

template<
    class T,
    class Container = vector<T>,
    class Compare = less<typename Container::value_type>
> class priority_queue;

这个 Compare 是类模板参数,你必须告诉编译器它是什么类型。如果你传的是一个函数指针 cmp,它就需要 decltype(&cmp) 来知道这个函数的类型。


✅ 所以为什么要 decltype(&cmp)

因为 cmp 是函数名,本身代表函数地址(函数指针)。你不能直接写:

priority_queue<..., cmp> q(cmp);  // ❌ 错误,cmp 不是一个类型

但你可以通过:

decltype(&cmp)  // 获取 cmp 的函数指针类型:bool (*)(const pair<int,int>&, const pair<int,int>&)

从而告诉编译器你传的是一个函数指针类型。


✅ 那 sort 为啥不用 decltype 呢?

因为 sort() 是函数模板,它第三个参数本身是一个函数对象,直接传一个函数或 lambda 就行了,编译器能推导出类型,不需要你显式说明。


✅ 最推荐的做法是用 struct 比较器,而不是 function 指针

你其实可以完全避免 decltype,写成这样:

struct Cmp {
    bool operator()(const pair<int, int>& a, const pair<int, int>& b) const {
        return a.first > b.first;
    }
};

priority_queue<pair<int, int>, vector<pair<int, int>>, Cmp> q;

这样更安全、支持 inline 优化,不涉及函数指针、decltype,写法更简洁。


✅ 一句话总结:

sort 用的是函数参数,编译器能自动推导类型,不用写类型名;而 priority_queue 的比较器是类模板参数,需要提前告诉编译器类型是什么,所以必须用 decltype(&cmp)struct Cmp 显式声明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值