如何让使用不同比较函数的Threshold模板类适配同一函数?
解决方案
问题根源
你的foo函数模板只接受默认比较器的Threshold<T>类型,但当你指定非默认的comp_func(比如std::less_equal)时,Threshold<T, std::less_equal<T>>和Threshold<T>是完全不同的类型,因此无法匹配foo的参数。你尝试用std::binary_function的思路无效,是因为std::greater_equal<T>/std::less_equal<T>是继承自std::binary_function<T,T,bool>,而非与它类型完全相同,std::is_same只会检查类型严格相等,所以那个约束条件永远不成立。
方案1:扩展foo的模板参数(最简洁)
直接让foo的模板参数包含comp_func,同时保留对T的算术类型约束:
template<typename T, typename Comp, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr> void foo(Threshold<T, Comp>& threshold) { // 你的函数逻辑 }
这样无论你使用哪种比较器,只要T是算术类型,foo都能匹配对应的Threshold实例。
方案2:C++20 概念简化约束
如果你的项目支持C++20,可以用概念替代enable_if,让代码更清晰:
#include <concepts> template<std::arithmetic T, typename Comp> void foo(Threshold<T, Comp>& threshold) { // 你的函数逻辑 }
方案3:通用模板+类型检查(灵活性更高)
如果不想在foo的模板参数里显式写出Threshold的模板参数,可以让foo接受任意类型,再通过内部检查确保它是合法的Threshold实例:
首先修改Threshold类,添加一个公开的value_type别名:
template<typename T, typename comp_func = std::greater_equal<T>, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr> class Threshold { public: using value_type = T; // 添加类型别名 Threshold(T threasholdValue) : _thresholdValue(threasholdValue) {} ~Threshold() = default; bool isExceeded(T value) const { return comp_func{}(value, _thresholdValue); } private: T _thresholdValue; };
然后编写foo:
template<typename ThresholdType> void foo(ThresholdType& threshold) { using T = typename ThresholdType::value_type; static_assert(std::is_arithmetic<T>::value, "Threshold must use an arithmetic type"); // 你的函数逻辑 }
这种方式不需要在foo的模板参数里重复Threshold的模板参数,同时通过static_assert保证类型合法性。
内容的提问来源于stack exchange,提问作者DaveR
相关产品推荐
相关产品推荐

