自定义类型作为map或者unordered_map的key需要额外做哪些事情

1、自定义类型作为map的key

在这里插入图片描述
map中有4个参数,前两个参数是key和val的类型,第三个参数表示比较的仿函数,用于对键值进行比较,默认情况下采用less<Key>,第四个参数表示分配器的类型,用于分配和管理内存。

在这里插入图片描述
如果key是内置类型,比如char,int等,使用默认的less<Key>不会错。
如果Key不是内置类型,在插入数据时就会产生一个编译错误

例如:

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
private:
	string name;
};

int main()
{
	map<Student, Student> treeMap;
	Student stu("fl");
	treeMap[stu] = stu;
	return 0;
}

在这里插入图片描述

在这里插入图片描述

要保证编译通过,需要在自定义类中重载<运算符或者显示的传入一个比较仿函数,或者普通函数,或者定义一个lambda表达式

方法1:在自定义类中重载<运算符

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
	bool operator<(const Student& stu) const
	{
		return name < stu.name;
	}
	string name;
};

int main()
{
	map<Student, Student> treeMap;
	Student stu("fl");
	treeMap[stu] = stu;
	return 0;
}

方法2:自定义比较函数

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
	string name;
};

bool StudentCmp(const Student& stu1, const Student& stu2)
{
	return stu1.name < stu2.name;
}

int main()
{
	map<Student, Student, decltype(StudentCmp)*> treeMap;
	Student stu("fl");
	treeMap[stu] = stu;
	return 0;
}

方法3:自定义比较仿函数

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
	string name;
};

class StudentCmp
{
public:
	bool operator()(const Student& stu1, const Student& stu2) const
	{
		return stu1.name < stu2.name;
	}
};

int main()
{
	map<Student, Student, StudentCmp> treeMap;
	Student stu("fl");
	treeMap[stu] = stu;
	return 0;
}

方法4:使用lambda表达式

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
	string name;
};


int main()
{
	auto cmp = [&](const Student& stu1, const Student& stu2) {
		return stu1.name < stu2.name;
	};
	map<Student, Student, decltype(cmp)> treeMap(cmp);
	Student stu("fl");
	treeMap[stu] = stu;
	return 0;
}

2、自定义类型作为unordered_map的key

在这里插入图片描述
unordered_map有5个参数,前两个参数是key和val的类型,第三个参数是一个哈希函数,表示用于计算哈希值,第四个参数是比较函数,用于判断两个键是否相等,第五个参数是分配器类型。

对于hash,可以支持任何的内置类型
在这里插入图片描述

对于比较函数equal_to,也支持任何的内置类型的比较

在这里插入图片描述

如果key是内置类型,对应默认的hash和equal_to完全够用,不会不错。
如果key是自定义类型,在插入数据时就会产生一个编译错误。

例如:

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
	string name;
};

int main()
{
	unordered_map<Student, Student> hashMap;
	Student stu("fl");
	hashMap[stu] = stu;
	return 0;
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
要保证编译通过,则需要在类中重载==操作符并且自定哈希函数或者自定义比较(可以是普通的函数,仿函数,lambda表达式)并且自定义哈希函数

方法1:在类中重载==操作符并且自定哈希函数

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
	string name;
	bool operator==(const Student& stu) const
	{
		return name == stu.name;
	}
};

class Studenthash
{
public:
	size_t operator()(const Student& stu) const
	{
		return std::hash<string>()(stu.name);
	}
};
int main()
{
	unordered_map<Student, Student, Studenthash> hashMap;
	Student stu("fl");
	hashMap[stu] = stu;
	return 0;
}

方法2:自定义比较(可以是普通的函数,仿函数,lambda表达式)并且自定义哈希函数

class Student
{
public:
	Student() = default;
	Student(string _name) :name(_name){}
	string name;
};

//我这里就写一个比较函数,除此之外还可以是仿函数,lambda表达式
bool StudentEqual(const Student& stu1, const Student& stu2)
{
	return stu1.name == stu2.name;
}

class Studenthash
{
public:
	size_t operator()(const Student& stu) const
	{
		return std::hash<string>()(stu.name);
	}
};

int main()
{
	unordered_map<Student, Student, Studenthash, decltype(StudentEqual)*> hashMap;
	Student stu("fl");
	hashMap[stu] = stu;
	return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值