You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:10:35