关于自定义unordered_set\unordered_map中Hash和KeyEqual:函数对象和lambda表达式简单应用

unordered_set为例,首先在cppreference中查看其模板定义:
image
可以看到Hash类默认是std::hash<KeyKeyEqual类似,本文将Hash以函数对象写出,将KeyEqual以lambda写出。

class hashvec{
	public:
	size_t operator()(const vector<int> & vec) const {
	return hash<int>()(vec[0]) + hash<int>()(vec[1]) + hash<int>()(vec[2]);
	}
};
int main() {
	unordered_set<vector<int>, hashvec, decltype([](const vector<int>& vec1,const vector<int>& vec2) -> bool{
			if (vec1[0] == vec2[0] && vec1[1] == vec2[1] && vec1[2] == vec2[2]) {
                return true;
            }
            return false;
        })> tmpres;
}

如上图,定义了一个unrodered_set,要注意的是:

  • 函数对象类hashvec中,重载的()运算符是一个const函数
  • undordered_set中的KeyEqual接收一个类,因此需要用decltype推断lambda的类型
  • 两个函数内部都不应该改变vec的值,因此参数都需要是const

需要注意的是,unordered_set的第三个模板参数只需要定义KeyEqual相等模板而不是Compare比较模板,因为unordered_set底层使用哈希表,不需对元素做比较大小,而只需比较两个元素是否相等即可;
image
set却要定义Compare模板类型,因为set底层使用红黑树,默认会排序set中的各个元素;


手动配置 c++ 堆队列:

priority_queue<pair<int, int>, vector<pair<int, int>>, decltype([](const pair<int, int> & p1, const pair<int, int> & p2) -> bool {
            if (p1.second <= p2.second)
                return true;
            else
                return false;
        })> priqu;

关于上述lambda表达式的使用,记录一个报错:

    unordered_map<vector<int>, unordered_set<int>, hashvec, decltype([](const vector<int> & p1, const vector<int> & p2) -> bool {
        if (p1[0] == p2[0])
            return true;
        return false;
    })> unmap;

以及上面定义的 priority_queue中lambda表达式的使用,报错:
image
上面这种定义在leetcode不会出现,但是在c++版本低于c++20会出现;
参考:
https://blog.csdn.net/yyz_1987/article/details/124953118
解决方法:
可以使用函数对象来替代;

posted @ 2024-07-03 19:29  SanFranciscoo  阅读(0)  评论(0)    收藏  举报