如何在C++函数定义中正确定义并使用std::less作为模板参数?
在C++中正确使用std::less作为模板参数的语法
问题场景
尝试将std::less<float>作为模板参数传递给order函数以实现比较逻辑,但编译报错。以下是原代码及错误信息:
原示例代码
#include <iostream> #include <functional> template<typename CMP> float order(float a, float b) { return CMP(a, b) ? a : b; // 编译错误 // return CMP::operator()(a,b) ? a : b; // 另一种尝试 // return (a CMP b) ? a : b; // ¯\_(ツ)_/¯ } int main() { const float A = order<std::less<float>>(3.1, 7.2); // 编译错误 const float B = order<std::greater<float>>(3.1, 7.2); std::cout << "A=" << A << "\n"; std::cout << "B=" << B << "\n"; return 0; }
编译错误信息
$ g++ -std=c++17 foo.cpp -o foo foo.cpp:6:12: error: no matching constructor for initialization of 'std::__1::less<float>' foo.cpp:12:21: note: in instantiation of function template specialization 'order<std::__1::less<float> >' requested here const float A = order<std::less<float>>(3.1, 7.2); ^
错误原因
std::less<float>是函数对象类,而非普通函数。原代码中CMP(a, b)试图用两个float参数构造该类的对象,但std::less的构造函数不需要任何参数,因此触发构造不匹配的错误。
正确实现方式
方式1:创建函数对象实例后调用operator()
这是最直接的修正方式,先实例化CMP类型的对象,再调用其operator()完成比较:
#include <iostream> #include <functional> template<typename CMP> float order(float a, float b) { CMP cmp; // 实例化比较器对象 return cmp(a, b) ? a : b; } int main() { const float A = order<std::less<float>>(3.1, 7.2); const float B = order<std::greater<float>>(3.1, 7.2); std::cout << "A=" << A << "\n"; // 输出A=3.1 std::cout << "B=" << B << "\n"; // 输出B=7.2 return 0; }
方式2:使用std::invoke统一处理可调用类型(C++17及以上)
std::invoke可以统一调用各种可调用实体(函数对象、函数指针、lambda等),代码更简洁:
#include <iostream> #include <functional> #include <utility> // 包含std::invoke template<typename CMP> float order(float a, float b) { // 创建临时CMP实例并调用 return std::invoke(CMP{}, a, b) ? a : b; } int main() { const float A = order<std::less<float>>(3.1, 7.2); const float B = order<std::greater<float>>(3.1, 7.2); std::cout << "A=" << A << "\n"; std::cout << "B=" << B << "\n"; return 0; }
方式3:将比较器作为函数参数传递(更灵活)
这种方式无需显式指定模板参数,编译器会自动推导比较器类型,同时支持传递带状态的自定义函数对象:
#include <iostream> #include <functional> template<typename CMP> float order(float a, float b, CMP cmp) { return cmp(a, b) ? a : b; } int main() { const float A = order(3.1, 7.2, std::less<float>{}); const float B = order(3.1, 7.2, std::greater<float>{}); std::cout << "A=" << A << "\n"; std::cout << "B=" << B << "\n"; return 0; }
内容的提问来源于stack exchange,提问作者wcochran
相关产品推荐
相关产品推荐

