41、如果`std::map`的键类型是自定义类型,需要怎么做?(附 仿函数)

在C++中使用自定义类型作为std::map的键时,必须定义键的比较规则,具体可通过以下两种方式实现:


方法一:在自定义类型中 重载运算符 <(优先)

在自定义类型中 重载小于运算符,确保能正确比较两个对象的大小关系。例如:

struct MyKey {
    int key;
    bool operator<(const MyKey& other) const {
        return key < other.key;
    }
};
std::map<MyKey, int> myMap;

方法二:自定义比较函数对象

如果无法修改自定义类型(例如类型来自第三方库),也就是不能在自定义类型中重载小于运算符,此时我们可定义一个**仿函数(Functor)**来操作这个自定义类型。在初始化map时,这个仿函数就作为 std::map 的第三个参数:

struct Key {
    int a, b;
    Key(int x, int y) : a(x), b(y) {}
};

struct CustomCompare {
    bool operator()(const Key& x, const Key& y) const {
        // 定义复合比较逻辑,例如优先比较a,再比较b
        if (x.a != y.a) return x.a < y.a;
        return x.b < y.b;
    }
};

std::map<Key, int, CustomCompare> myMap; // 使用自定义比较规则

注:C++ 仿函数详解

定义:仿函数(Functor)是 重载函数调用运算符operator() 的类对象,使其能像函数一样被调用。本质上它的对象(实例)是一个函数对象,兼具函数和对象的特性。

基本实现

class Adder {
public:
    int operator()(int a, int b) const {
        return a + b;
    }
};

// 使用示例
Adder add;
int result = add(3, 5);  // 输出8

进阶示例

1. 带状态的仿函数

class Counter {
    int count = 0;
public:
    void operator()(int x) {
        count += x;
        std::cout << "Current total: " << count << std::endl;
    }
};

int main() {
    Counter cnt;
    cnt(10);  // 输出10
    cnt(5);   // 输出15,同一个对象,会累加
    cnt(3);   // 输出18
}

2. 模板仿函数

Cpptemplate<typename T>
class Multiplier {
public:
    T operator()(T a, T b) {
        return a * b;
    }
};

STL应用场景

std::vector<int> nums {5, 3, 8, 1};
std::sort(nums.begin(), nums.end(), std::greater<int>());  // 使用预定义仿函数降序排序

// 自定义排序规则(仿函数)
struct CustomCompare {
    bool operator()(int a, int b) {
        return (a % 3) < (b % 3);
    }
};
std::sort(nums.begin(), nums.end(), CustomCompare());

与lambda表达式对比(C++11+)

// lambda实现相同功能
std::for_each(nums.begin(), nums.end(), [](int x){
    std::cout << x * 2 << " ";
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值