如何创建支持自定义比较器的C++函数?
解决兼容任意比较器的
special_push函数实现问题 你的需求是让special_push支持三种调用形式:无比较器(默认用less<int>)、传入标准 functor(比如less<int>)、传入自定义函数指针(比如mycomp),但当前的模板函数实现存在模板参数推导的问题,我来帮你修复它。
问题分析
你当前的模板函数:
template< typename _Compare > void push (deque<int> & qu,int val, _Compare comp = less<int>()) { while(qu.empty()==false && comp(val, qu.back())) { qu.pop_back(); } qu.push_back(val); }
当调用special_push(qu, 3)时,编译器无法推导模板参数_Compare——因为模板参数推导阶段不会考虑函数的默认参数,编译器不知道_Compare应该是什么类型,所以这个调用会编译失败。
解决方案
这里提供两种可行的实现方式,都能满足你的需求:
方案1:函数重载(兼容C++98及以上)
我们可以写一个不带比较器的重载函数,内部调用模板版本并传入默认的less<int>,同时保留模板版本用于接收自定义比较器:
#include <deque> #include <functional> using namespace std; // 模板版本:接收任意比较器 template<typename Compare> void special_push(deque<int>& qu, int val, Compare comp) { while (!qu.empty() && comp(val, qu.back())) { qu.pop_back(); } qu.push_back(val); } // 重载版本:无比较器时,默认使用less<int> void special_push(deque<int>& qu, int val) { special_push(qu, val, less<int>()); } // 自定义比较器 bool mycomp(int a, int b) { return a < b; } int main () { deque<int> qu; special_push(qu, 3); // 调用重载版本 special_push(qu, 5, less<int>()); // 调用模板版本,接收functor special_push(qu, 5, mycomp); // 调用模板版本,接收函数指针 }
方案2:默认模板参数(C++11及以上)
利用C++11支持的默认模板参数,直接给模板参数指定默认值,同时函数参数也用默认构造的比较器:
#include <deque> #include <functional> using namespace std; template<typename Compare = less<int>> void special_push(deque<int>& qu, int val, Compare comp = Compare()) { while (!qu.empty() && comp(val, qu.back())) { qu.pop_back(); } qu.push_back(val); } bool mycomp(int a, int b) { return a < b; } int main () { deque<int> qu; special_push(qu, 3); // 使用默认模板参数less<int>,默认构造comp special_push(qu, 5, less<int>()); // 显式传入less<int>实例 special_push(qu, 5, mycomp); // 模板参数推导为bool(*)(int,int),传入函数指针 }
说明
- 两种方案都能完美支持你需要的三种调用形式:无比较器、标准functor、自定义函数指针。
- 方案1兼容性更好,能在C98环境下工作;方案2更简洁,适合C11及以后的项目。
- 注意函数参数中的
comp(val, qu.back())逻辑:当前是当val小于qu.back()时弹出尾部元素,这和std::sort的比较器逻辑一致(比较器返回true表示第一个参数应该排在第二个参数前面)。
内容的提问来源于stack exchange,提问作者Hector Ricardez
相关产品推荐
相关产品推荐

