std::map 自定义类型为key,需重载小于运算符
虽然这个问题从学C++就知道,但最近面试的时候,面试官问如果map要使用自定义类型作为key行不行。 我一想他肯定是要问我实现operator <的问题,然后我说了一个不一定哦~ 不必要哦~ 特此记录一下。
一般来说当申明map对象的时候,需要传入支持绝对小于运算的类型作为key:
#include <iostream> #include <map> struct Key { int a; int b; explicit Key(int x, int y) : a(x), b(y) { } bool operator<(const Key& other) const { if (other.a >= a) { return true; } if (other.a < a and other.b >= b) { return true; } return false; } }; std::ostream& operator<<(std::ostream& os, const Key& self) { os << "{" << self.a << ", " << self.b << "}"; return os; } int main() { std::map<Key, int, Less> mp{ { Key(3, 4), 233}}; mp.insert({ Key(1, 2), 111}); for (auto&& i : mp) { const auto [a, b] = i; std::cout << a << "->" << b << std::endl; } }
{ 1, 2}->111 { 3, 4}->233
我们都知道map在插入,删除,查找时会按照二叉树规律去比较节点的key值,默认会使用Key类型提供的<去标胶对象大小。如果在构造时没有传入第三参数比较运算对象,就调用该对象提供的仿函数替换原有<,或者如果没有重载<将使用该对象。gnu C++ 源码:
template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > class map { ... };
而有一次我在构造map对象的时候传入了比较运算对象
struct Key { int a; int b; explicit Key(int x, int y) : a(x), b(y) { } }; struct Less { // std::map采用此规则,变成了从大到小排 auto operator()(const Key& x, const Key& y) { if (x.a >= y.a) { return true; } if (x.a < y.a and x.b >= y.b) { return true; } return false; } }; { std::map<Key, int, Less> mp{ { Key(3, 4), 233}}; // 使用Less作为第三参数实例化模板 mp.insert({ Key(1, 2), 111}); }
{ 3, 4}->233 { 1, 2}->111