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

为何模板函数可作为std::sort参数,模板lambda却无法使用?

模板Lambda传递给std::sort的语法问题

问题描述

以下基于模板函数的代码可正常运行,实现按结构体S的b成员排序:

#include <algorithm>
#include <iostream>
#include <vector>

struct S { int a{}, b{}; };
std::ostream &operator<<(std::ostream &o, const S &s) { return o << '{' << s.a << ',' << s.b << '}'; }

template <auto ptr>
bool f(const S &a, const S &b)
{
    return a.*ptr < b.*ptr;
}

int main()
{
    std::vector<S> v{{1,9},{2,8},{3,7},{4,6},{6,4},{7,3},{8,2},{9,1}};

    std::sort(v.begin(), v.end(), f<&S::b>);

    for (const auto &s : v)
        std::cout << s << ' ';

    return 0;
}

但改用模板Lambda时,编译器会误将模板参数语法<&S::b>解析为小于运算符,导致编译失败:

// 续上面的main函数
auto l = []<auto ptr>(const S &a, const S &b)
{
    return a.*ptr < b.*ptr;
};

std::sort(v.begin(), v.end(), l<&S::b>); // 此处编译报错

报错信息:

error: no match for 'operator<' (operand types are 'main()::<lambda(const S&, const S&)>' and 'int S::*')
std::sort(v.begin(), v.end(), l<&S::b>);
                              ~^~~~~~

解决方案

方法1:显式调用模板化operator()并包装为普通Lambda

模板Lambda的模板参数定义在operator()成员函数上,需用.template关键字明确告知编译器后续的<是模板参数列表而非小于运算符,将其包装为普通Lambda后传递给std::sort:

std::sort(v.begin(), v.end(), [&l](const S& a, const S& b) {
    return l.template operator()<&S::b>(a, b);
});

方法2:直接在std::sort参数中定义带默认模板参数的Lambda

若无需复用该模板Lambda,可直接在std::sort参数内定义Lambda并指定默认模板参数,简化写法:

std::sort(v.begin(), v.end(), []<auto ptr = &S::b>(const S& a, const S& b) {
    return a.*ptr < b.*ptr;
});

方法3:获取模板化operator()的实例地址

直接通过.template operator()<&S::b>获取模板实例化后的可调用对象地址,传递给std::sort:

std::sort(v.begin(), v.end(), l.template operator()<&S::b>);

内容的提问来源于stack exchange,提问作者PaperBirdMaster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:13:12