如何用struct作为map的Key

doudoushen 2010-12-09 06:44:40
struct EntryInfo
{
EntryInfo()
{
memset( this, 0, sizeof(EntryInfo) );
}

char achEntryName[16];
byte byEntryType;
byte byAddrType;
WORD wDialBitRate;
char achUIName[16];

BOOL operator == ( const EntryInfo &tEntry ) const
{
if ( byEntryType != tEntry.byEntryType )
return FALSE;
if( byAddrType != tEntry.byAddrType )
return FALSE;
if ( strcmp( achEntryName, tEntry.achEntryName ) != 0 )
return FALSE;
return TRUE;
}

BOOL operator < ( const EntryInfo &tEntry ) const
{
if( this->byEntryType > tEntry.byEntryType )
{
return FALSE;
}
else if(this->byEntryType == tEntry.byEntryType)
{
if( this-> byAddrType > tEntry.byAddrType )
{
return FALSE;
}
else if( strcmp(this->achEntryName, tEntry.achEntryName) >0 )
{
if( strcmp( this->achUIName, tEntry.achUIName ) > 0 )
{
return TRUE;
}
else
{
return FALSE;
}

}
else
{
return TRUE;
}
}
else
{
return TRUE;
}


}
};


typedef map<EntryInfo, int> defMap;
defMap g_map;



void CStl_mapDlg::OnButton2()
{


EntryInfo t1;
strcpy(t1.achEntryName, "sq");
strcpy(t1.achUIName, "sq_UI");
t1.byAddrType = 1;
t1.byEntryType =1;
t1.wDialBitRate = 1;
g_map.insert( defMap::value_type(t1, 1));


EntryInfo t2;
strcpy(t2.achEntryName, "sq2");
strcpy(t2.achUIName, "sq_UI2");
t2.byAddrType = 2;
t2.byEntryType =2;
t2.wDialBitRate = 2;
g_map.insert( defMap::value_type(t2, 2));

EntryInfo t3;
strcpy(t3.achEntryName, "sq3");
strcpy(t3.achUIName, "sq_UI3");
t3.byAddrType = 3;
t3.byEntryType =3;
t3.wDialBitRate = 3;
g_map.insert( defMap::value_type(t3, 3));


}

void CStl_mapDlg::OnButton3()
{

EntryInfo t3;
strcpy(t3.achEntryName, "sq3");
strcpy(t3.achUIName, "sq_UI3");
t3.byAddrType = 3;
t3.byEntryType =3;
t3.wDialBitRate = 3;
int x = g_map[t3];//饭后一直是0

}
...全文
621 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhaoli_1956 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 bluewanderer 的回复:]

楼下解释T T 俺无奈了...
[/Quote]
同情你,哈哈
bluewanderer 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 q191201771 的回复:]
我想当然的认为起码key要能比较
当时楼上说需要<即可
期待高手解答
另外一楼说的64位是哪看的?
[/Quote]

其实... map默认情况下比较调用的就是less

64位那个是经验范畴:1. 目前基本类型没有超过64位的;2. 超过8字节复制速度就开始下降(从一个write变成多个write;虽说有个例外就是对齐的64字节又变成一个write,但减小的只是总线压力,指令压力已经变成8倍了);3. 没有哪儿当真建议过谁不用指针或者引用传超过64位的参数的貌似。

当然既然64位就是个经验值,那就也不是绝对的。但是lz那个已经上百位了我想说=-=b...
dubiousway 2010-12-10
  • 打赏
  • 举报
回复
如果把 operator< 简单的改成

if(strcmp(achEntryName,tEntry.achEntryName)< 0)
return true;
else return false;

那么就能找到int x = g_map[t3]

但是写成

if(strcmp(achEntryName,tEntry.achEntryName)<= 0)
return true;
else return false;

x 就成0了
doudoushen 2010-12-10
  • 打赏
  • 举报
回复
hai040 是正确的 谢谢
doudoushen 2010-12-10
  • 打赏
  • 举报
回复
hai040 是正确的 谢谢
doudoushen 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 hai040 的回复:]
一样的啊
this-> byAddrType > tEntry.byAddrType
=的时候都是true
[/Quote]

不是很明白 当this-> byAddrType == tEntry.byAddrType 返回TRUE为什么不对? 假设我能确保任意2个byAddrType byEntryType都不相同 应该可以的吧 比如例子中3个byAddrType byEntryType都不相同

dubiousway 2010-12-10
  • 打赏
  • 举报
回复
18 楼说的对。

最后我才发现 lz 定义 operator<

用的是 “不大于 就是小”,也就是 <= 都是小, 这样 对比相同字符串的时候,等于,就是小于,,永远找不到了
chengzhe 2010-12-10
  • 打赏
  • 举报
回复
我觉得是可行的
hai040 2010-12-10
  • 打赏
  • 举报
回复
一样的啊
this-> byAddrType > tEntry.byAddrType
=的时候都是true
doudoushen 2010-12-10
  • 打赏
  • 举报
回复
hai040

(hai)


如果我只考虑2个int值 不比较字符串 好像也不行 代码如下
	bool operator < ( const EntryInfo &tEntry ) const
{
if( this->byEntryType > tEntry.byEntryType )
{
return FALSE;
}
else if(this->byEntryType == tEntry.byEntryType)
{
if( this-> byAddrType > tEntry.byAddrType )
{
return FALSE;
}
// else if( strcmp(this->achEntryName, tEntry.achEntryName) >0 )
// {
// if( strcmp( this->achUIName, tEntry.achUIName ) > 0 )
// {
// return TRUE;
// }
// else
// {
// return FALSE;
// }
//
// }
else
{
return TRUE;
}
}
else
{
return TRUE;
}

return FALSE;
}
hai040 2010-12-10
  • 打赏
  • 举报
回复
<要保证a<b&&b<a为false
else if( strcmp(this->achEntryName, tEntry.achEntryName) >0 )
{
...
}
else
{
return TRUE;
}
这里当结果为0时两个都是true
doudoushen 2010-12-10
  • 打赏
  • 举报
回复
不是编译不过 是返回值不正确

EntryInfo t3;
strcpy(t3.achEntryName, "sq3");
strcpy(t3.achUIName, "sq_UI3");
t3.byAddrType = 3;
t3.byEntryType =3;
t3.wDialBitRate = 3;
int x = g_map[t3];//返回值一直是0

dubiousway 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 doudoushen 的回复:]

dubiousway
(酆花血月)

不行啊
[/Quote]

你的问题到底是什么? 编译通不过吗?

我把你前面的部分,和OnButton2里的拿出来编译了,除了BOOL 有警告(改成bool就没了),其他没问题啊
doudoushen 2010-12-10
  • 打赏
  • 举报
回复
dubiousway
(酆花血月)

不行啊
dubiousway 2010-12-10
  • 打赏
  • 举报
回复
BOOL operator < ( const EntryInfo &tEntry ) const

改成:

bool operator < ( const EntryInfo &tEntry ) const

试试
doudoushen 2010-12-10
  • 打赏
  • 举报
回复
说我没有重载 < 和==的朋友 ,请稍微看下我的代码 我有重载的
问题是重载了也没用 不知道哪里错了


我甚至试过 重载<的时候 直接返回true 也是不行的 。另外 如果断点打在BOOL operator < ( const EntryInfo &tEntry ) const函数里面 程序能够走进来
就想叫yoko 2010-12-09
  • 打赏
  • 举报
回复
我想当然的认为起码key要能比较
当时楼上说需要<即可
期待高手解答
另外一楼说的64位是哪看的?
bluewanderer 2010-12-09
  • 打赏
  • 举报
回复
如果Key或者Value是比较大的结构体的话,这里产生一个问题就是所有操作都需要复制大块的数据,而且删除的时候搞不好还要复制好几次大块的数据。...相当粗鲁。
qq120848369 2010-12-09
  • 打赏
  • 举报
回复
只需要重载struct的<运算符即可,或者和bluewanderer那样,写一个仿函数类,作为模板形参传赋给map使用.

#include <iostream>
#include <map>
using namespace std;

typedef struct S
{
public:
S(int i):m(i)
{
}

S(const S &obj):m(obj.m)
{
}

bool operator <(const S &obj) const //因为less类里的operator()有const
{
return m < obj.m;
}

~S()
{
}

private:
int m;

}Struct;

int main()
{
map<Struct,int> mp; //less<>默认使用对象的<运算符,所以重载对象的<是OK的

//只需要重载<,原因:
//平衡二叉树:
/*
less<Struct> cmp;
if(cmp(a->data,b->data)) a是待插入结点,b是当前结点,data是结点里Struct对象
{
go to left ;
}

// 已知a>=b,需要判断b<a还是b==a

else if(cmp(b->data,a->data)) //如果b<a成立,那么走右边
{
go to right;
}
else //b==a,由于是map不是multi_map,报错
{
throw ....
}

*/

Struct a(1);
Struct b(3);
Struct c(2);

mp.insert(make_pair(a,1));
mp.insert(make_pair(b,1));
mp.insert(make_pair(c,1));

return 0;
}
healer_kx 2010-12-09
  • 打赏
  • 举报
回复
重载 < 和 ==
加载更多回复(8)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧