c++中以类对象作为key用于unordered_map、map,以及std::tie技巧使用

我有一个类

class UserRegion {
public:
    int country_id;
    int province_id;
    int isp_id;
}

如果想让其作为std::unordered_map的key的话需要添加两个条件:

  • 1、operator==,用于查找
  • 2、实现对应的hash类
#include 
#include 
// 用于表示用户区域信息
class UserRegion {
public:
    int country_id;
    int province_id;
    int isp_id;

    bool operator==(const UserRegion& other) const {
        return country_id == other.country_id && province_id == other.province_id &&
               isp_id == other.isp_id;
    }
};

struct HashUserRegion {
    std::size_t operator()(const UserRegion& ur) const {
        std::size_t h1 = std::hash<int>{}(ur.country_id);
        std::size_t h2 = std::hash<int>{}(ur.province_id);
        std::size_t h3 = std::hash<int>{}(ur.isp_id);
        return h1 ^ (h2 << 1) ^ (h3 << 2);
    }
};

int main() {
    std::unordered_map<UserRegion, std::string, HashUserRegion> user_region_map = {
            {{1, 1, 1}, "user1"},
            {{1, 2, 1}, "user2"},
            {{2, 1, 2}, "user3"}
    };
    UserRegion test = {1, 1, 1};
    if (user_region_map.find(test) != user_region_map.end()) {
        std::cout << user_region_map[test] << std::endl;
    }
    // 遍历 unordered_map
    for (auto it = user_region_map.begin(); it != user_region_map.end(); ++it) {
        const UserRegion &ur = it->first;
        const std::string &user_name = it->second;
        std::cout << user_name << std::endl;
    }
    return 0;
}

如果想让其作为std::map的key的话需要添加一个条件:

  • 1、operator<,用于查找
    首先我们逻辑是按照成员顺序挨个比较,注意这里最里层的比较不能是<=,小于比较运算符返回 false 时,才认为相等。
bool operator<(const UserRegion& other) const {
    if (country_id < other.country_id) return true;
    else if (country_id == other.country_id) {
        if (province_id < other.province_id) return true;
        else if (province_id == other.province_id) {
            if (isp_id < other.isp_id) return true;
            else return false;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

当比较多个成员变量时,可以使用 std::tie 函数来简化比较操作。std::tie 函数可以将多个变量绑定在一起,形成一个元组,然后使用元组的比较操作符进行比较。这样可以避免手动编写多个比较操作符,从而简化代码。

使用 std::tie 函数重写 operator< 函数的示例代码如下:

bool operator<(const UserRegion& other) const {
    return std::tie(country_id, province_id, isp_id) <
           std::tie(other.country_id, other.province_id, other.isp_id);
}

在这个例子中,std::tie 函数将 country_id、province_id 和 isp_id 绑定在一起,形成一个元组。然后使用 < 运算符比较两个元组,从而实现了 UserRegion 结构体的比较操作。这种写法简洁明了,易于理解和维护。
需要注意的是结构体的成员变量应该是不可变的,以避免在哈希表or红黑树中修改键值对。如果在哈希表or红黑树中修改键值对,将会导致哈希表or红黑树的内部结构被破坏,从而导致未定义的行为。

你可能感兴趣的:(#,C++,挖坑与填坑,#,前后端开发功能代码库,c++,哈希算法,开发语言)