C++14模板类如何为浮点类型添加带epsilon参数的方法重载?
实现方案说明
你的需求在C++14 + GCC 10的运行环境下完全可以实现,现有代码的核心问题是成员函数模板的模板参数名和类模板的参数名重名了,会导致外层类的ValueType被遮蔽,调整参数名后即可正常运行。
修正后的可运行代码示例
#include <type_traits> #include <cmath> template<typename ValueType> class Comparator { public: // 通用版本,所有类型都可调用 bool passed(ValueType actualValue) { // 此处为示例逻辑,可替换为你实际的判断规则 return actualValue == expectedValue; } // 仅浮点类型可用的带精度阈值的重载 template< typename T = ValueType, // 不要和类模板参数重名,默认取类的模板参数值 typename = std::enable_if_t< std::is_floating_point<std::remove_reference_t<T>>::value > > bool passed(T actualValue, T eps) { // 浮点精度比较示例逻辑 return std::abs(actualValue - expectedValue) < eps; } private: ValueType expectedValue{}; // 示例预设期望值,可根据你的业务调整 };
核心注意事项
- 成员函数模板的参数名不能和类模板参数名重复,否则会触发名称遮蔽,导致SFINAE限制失效
- 成员模板参数默认值设为类的
ValueType,可以保证调用时不需要显式指定模板参数,直接传参即可匹配到对应重载 - 非浮点类型调用带两个参数的
passed方法时会直接编译报错,符合你要求的调用限制
调用测试示例
int main() { Comparator<int> int_comp; int_comp.passed(10); // 正常编译,调用通用版本 // int_comp.passed(10, 1); // 编译失败,int不属于浮点类型,无对应重载 Comparator<double> double_comp; double_comp.passed(3.14); // 正常编译,调用通用版本 double_comp.passed(3.14, 1e-6); // 正常编译,调用浮点专属重载 return 0; }
内容的提问来源于stack exchange,提问作者Валентин Никин
相关产品推荐
相关产品推荐

