在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 << " ";
});