map、set插入自定义数据类型作为key时需要注意什么问题问题?!!!!!!!!
首先要解决排序问题,方法有:
1.重载自定义数据类型的operator<()操作符
2.map类型的第三个参数为函数对象类类型,可以自定义这个比较函数的函数对象,
如申明一个类似
struct CustomLess
{
bool operator()(const CustomKey2& other1, const CustomKey2& other2)
{
return other1.a < other2.a || (other1.a == other2.a && other1.b < other2.b);
}
};
的函数对象,将其作为map申明类型的第三个参数类型传入
3.利用std::function封装一个
typedef std::function<bool(const CustomKey2&, const CustomKey2&)> FuncType;
将FuncType作为map的第三个参数,并在定义map对象时传入一个FuncType的可执行体,如对对应的普通函数指针,函数对象,Lambda表达式等
4.对map的第三个参数类型less函数的进行模板定制-可以全特化
模板特化匹配优先级:全特化 > 偏特化 > 主模板
#include <map>
#include <string>
#include <iostream>
#include <functional>
using namespace std;
/************************************************************************/
/*
map、set插入自定义数据类型作为key时需要注意什么问题问题?!!!!!!!!
首先要解决排序问题,方法有:
1.重载自定义数据类型的operator<()操作符
2.map类型的第三个参数为函数对象类类型,可以自定义这个比较函数的函数对象,
如申明一个类似
struct CustomLess
{
bool operator()(const CustomKey2& other1, const CustomKey2& other2)
{
return other1.a < other2.a || (other1.a == other2.a && other1.b < other2.b);
}
};
的函数对象,将其作为map申明类型的第三个参数类型传入
3.利用std::function封装一个
typedef std::function<bool(const CustomKey2&, const CustomKey2&)> FuncType;
将FuncType作为map的第三个参数,并在定义map对象时传入一个FuncType的可执行体,如对对应的普通函数指针,函数对象,Lambda表达式等
4.对map的第三个参数类型less函数的进行模板定制-可以全特化
模板特化匹配优先级:全特化 > 偏特化 > 主模板
*/
/************************************************************************/
/*
std::map类型的定义头部模板参数
template<class _Kty,
class _Ty,
class _Pr = less<_Kty>,
class _Alloc = allocator<pair<const _Kty, _Ty> > >
第1个参数存储了key。
第2个参数存储了mapped value。
第3个参数是比较函数的函数对象。map用它来判断两个key的大小,并返回bool类型的结果。利用这个函数,map可以确定元素在容器中遵循的顺序以及两个元素键是否相等(!comp(a,b)&&!comp(b,a)),确保map中没有两个元素可以具有等效键。这里,它的默认值是less<Key>,定义如下
std::map的部分构造函数:
map()
: _Mybase(key_compare())
{ // construct empty map from defaults
}
// 入参时比较函数或对象
explicit map(const key_compare& _Pred)
: _Mybase(_Pred)
{ // construct empty map from comparator
}
// map默认比较函数对象 less<_Kty>
template<class _Ty = void>
struct less
{ // functor for operator<
typedef _Ty first_argument_type;
typedef _Ty second_argument_type;
typedef bool result_type;
constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};
*/
// 自定义数据key
struct CustomKey1
{
CustomKey1()
{}
CustomKey1(int ai, int bi): a(ai), b(bi)
{}
// 方法1,重写<操作符
bool operator<(const CustomKey1& other) const // 注意这里的两个const
{
return a < other.a || (a == other.a && b < other.b);
}
int a = 1;
int b = 2;
};
// 测试重载<操作符
void Test_Operator_CustomKey1()
{
std::map<CustomKey1, int> mapCustomKeyInt;
mapCustomKeyInt.insert(std::make_pair(CustomKey1(1, 2), 1));
mapCustomKeyInt.insert(std::make_pair(CustomKey1(1, 3), 1));
}
struct CustomKey2
{
CustomKey2()
{}
CustomKey2(int ai, int bi) : a(ai), b(bi)
{}
int a = 1;
int b = 2;
};
// 2.将map类型的第三个参数函数对象类型重写
struct CustomLess
{
bool operator()(const CustomKey2& other1, const CustomKey2& other2)
{
return other1.a < other2.a || (other1.a == other2.a && other1.b < other2.b);
}
};
// 将map类型的第三个参数函数对象类型重写
void Test_CustomLess()
{
std::map<CustomKey2, int, CustomLess> mapCustomKeyInt;
/*CustomLess c;
std::map<CustomKey2, int, CustomLess> mapCustomKeyInt(c);*/ // 也可以传入CustomLess这个可执行对象
mapCustomKeyInt.insert(std::make_pair(CustomKey2(1, 2), 1));
mapCustomKeyInt.insert(std::make_pair(CustomKey2(1, 3), 1));
}
// 3.使用std::function 将 一个可以比较的函数或函数对象打包生成一个可调用对象
bool CompareFunc(const CustomKey2& other1, const CustomKey2& other2) // 普通函数
{
return other1.a < other2.a || (other1.a == other2.a && other1.b < other2.b);
}
void Test_CompareFunc()
{
typedef std::function<bool(const CustomKey2&, const CustomKey2&)> FuncType;
std::map<CustomKey2, int, FuncType> mapCustomKeyInt(CompareFunc);
mapCustomKeyInt.insert(std::make_pair(CustomKey2(1, 2), 1));
mapCustomKeyInt.insert(std::make_pair(CustomKey2(1, 3), 1));
}
//4.全特化map默认的比较函数对象less
template<>
struct std::less <CustomKey2>
{ // functor for operator<
bool operator()(const CustomKey2& other1, const CustomKey2& other2) // 普通函数
{
return other1.a < other2.a || (other1.a == other2.a && other1.b < other2.b);
}
};
void Test_less()
{
std::map<CustomKey2, int> mapCustomKeyInt;
mapCustomKeyInt.insert(std::make_pair(CustomKey2(1, 2), 1));
mapCustomKeyInt.insert(std::make_pair(CustomKey2(1, 3), 1));
}
int main()
{
Test_Operator_CustomKey1();
Test_CustomLess();
Test_CompareFunc();
Test_less();
getchar();
return 0;
}