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

如何从成员指针模板类型获取类类型以实现通用排序模板

解决order_by模板依赖具体类型的问题

要让你的order_by模板完全独立于具体类类型,核心是从成员指针类型中自动推导类类型和成员类型,不需要硬编码Person这类具体类型。下面是具体的改造方案:

1. 改造order_by模板

我们可以利用C++的模板参数推导,直接从成员指针Member Class::*中解析出所属的类Class和成员类型Member,让模板完全通用:

#include <functional>
#include <vector>
#include <algorithm>
#include <string>

struct Person { std::string name; int age, height; };

// 通用的order_by模板:自动推导类类型和成员类型
template <typename Class, typename Member>
auto order_by(Member Class::*member_ptr) {
    return [member_ptr](const Class& a, const Class& b) {
        return a.*member_ptr < b.*member_ptr;
    };
}

这个模板的原理是:当你传入&Person::age时,编译器会自动匹配Class=Person、Member=int,生成针对Person类型的lambda,完全不需要显式指定类类型。

2. 保留并适配链式比较的operator|

你之前写的operator|模板已经是通用的了(因为用了auto参数),可以直接和改造后的order_by配合使用,仅做一点小优化让参数更严谨:

// 通用的链式比较组合模板
template<class F1, class F2>
auto operator|(F1 f1, F2 f2) {
    return [f1, f2](const auto& a, const auto& b) {
        const bool res = f1(a, b);
        const bool inv_res = f1(b, a);
        // 如果两次比较结果不同,说明a和b有大小关系,返回第一次结果;否则用第二个规则
        if (res != inv_res) return res;
        return f2(a, b);
    };
}

这里把参数改成const auto&可以避免不必要的拷贝,同时保持对任意类型的兼容性。

3. 测试示例用法

现在你可以像之前一样正常使用,而且order_by可以支持任何自定义类型:

int main() {
    std::vector<Person> persons = {
        {"Alice", 25, 165},
        {"Bob", 30, 180},
        {"Charlie", 25, 170}
    };

    // 按age找最大元素
    auto result = std::max_element(persons.begin(), persons.end(), order_by(&Person::age));
    // 输出Bob(年龄30最大)

    // 先按age排序,age相等时按height找最大
    result = std::max_element(persons.begin(), persons.end(), order_by(&Person::age) | order_by(&Person::height));
    // 输出Charlie(年龄25,身高170比Alice高)

    return 0;
}

额外优化(可选)

如果想要支持更多比较逻辑(比如降序、大于比较),可以扩展模板,增加一个比较器参数,默认用std::less<>:

template <typename Class, typename Member, typename Comparator = std::less<>>
auto order_by(Member Class::*member_ptr, Comparator comp = {}) {
    return [member_ptr, comp](const Class& a, const Class& b) {
        return comp(a.*member_ptr, b.*member_ptr);
    };
}

// 用法示例:按age降序
auto desc_age = order_by(&Person::age, std::greater<>());

这样你的模板会更加灵活,能适配更多排序场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 08:58:16