小于符号重载问题

小鱼儿霸 2013-01-30 04:46:20
typedef struct tagBigramPairRecord
{
std::string aph;
std::string name;
int count;
int distance;

tagBigramPairRecord()
{
aph = "";
name = "";
count = 0;
distance = 0;
}

bool operator<(const tagBigramPairRecord & rsc) const
{
if (aph < rsc.aph)
{
return true;
}
if (aph > rsc.aph)
{
return false;
}
if (name < rsc.name)
{
return true;
}
return false;
}

bool operator==(const tagBigramPairRecord & rsc) const
{
if (aph == rsc.aph && name == rsc.name)
{
return true;
}
return false;
}
} BigramPairRecord;


set<BigramPairRecord> candidate_records;
set<BigramPairRecord>::iterator set_iter = candidate_records.find(stBigramPairRecord);
if (set_iter != candidate_records.end())
{
set_iter->count += stBigramPairRecord.count;
set_iter->distance += stBigramPairRecord.distance;
}


错误:
error: assignment of data-member 'tagBigramPairRecord::count' in read-only structure

请指点!
...全文
274 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
小鱼儿霸 2013-01-30
  • 打赏
  • 举报
回复
1、疑问: 难道set返回的iterator就不能修改么?这个太奇怪了吧。 2、我自己的解决办法: 把struct中要修改的两个数据成员加了mutable。这样可以编译通过了,程序运行正确,但是这样太怪了啊。 3、思考: 仔细想想似乎可以理解了,虽然我放在set中的元素排序(operator)只用到了aph、name两个字段,期望count、distance是可以修改的字段,但是stl并不知道,认为只要元素(元素就是key)发生变化就会破坏树结构,因此编译器是不允许这样做的。对比思考一下map,key肯定是不能变的,变的是value。总结一下,本人特别喜欢用set,理由是比map看起来紧凑,看来实不可取,只要“元素”或“部分元素”可能发生变化,就应该拆成key-value结构放到map中。 4、非常感谢各位的回复。thx
rocktyt 2013-01-30
  • 打赏
  • 举报
回复
不好意思上面的发错了

    if (set_iter != candidate_records.end())
    {
        BigramPairRecord tmpRecord(*set_iter);
        tmpRecord.count    += stBigramPairRecord.count;
        tmpRecord.distance += stBigramPairRecord.distance;
        candidate_records.erase(set_iter++);
        candidate_records.insert(set_iter, tmpRecord)
    }
正确的修改方法,但是估计这不是lz想要的,因此给出另外一种不太推荐的方法

        const_cast<int&>(set_iter->count) += stBigramPairRecord.count;
        const_cast<int&>(set_iter->distance) += stBigramPairRecord.distance;
rocktyt 2013-01-30
  • 打赏
  • 举报
回复
ls的是错的,先删除了怎么再取?

    if (set_iter != candidate_records.end())
    {
        BigramPairRecord tmpRecord(*set_iter);
        tmpRecord.count    += stBigramPairRecord.count;
        tmpRecord.distance += stBigramPairRecord.distance;
        candidate_records.erase(BigramPairRecord++);
        candidate_records.insert(BigramPairRecord, tmpRecord)
    }
正确的修改方法,但是估计这不是lz想要的,因此给出另外一种不太推荐的方法

        const_cast<int&>(set_iter->count) += stBigramPairRecord.count;
        const_cast<int&>(set_iter->distance) += stBigramPairRecord.distance;
youyou1912 2013-01-30
  • 打赏
  • 举报
回复
set内部用树来保存, 如果随便修改里面值的话, 也就造成树结构被破坏了. 所以set的iterator实际是const 指针, 如果要修改, 需要先删除再添加.

	void test() 
	{
		BigramPairRecord stBigramPairRecord;
		set<BigramPairRecord> candidate_records;
		set<BigramPairRecord>::iterator set_iter = candidate_records.find(stBigramPairRecord); 
		if (set_iter != candidate_records.end())
		{
			candidate_records.erase(set_iter);
			BigramPairRecord newOne(*set_iter);
			newOne.count    += stBigramPairRecord.count;
			newOne.distance += stBigramPairRecord.distance;
			candidate_records.insert(newOne);
			//set_iter->count    += stBigramPairRecord.count;
			//set_iter->distance += stBigramPairRecord.distance;
		}
	}
rocktyt 2013-01-30
  • 打赏
  • 举报
回复
此问题与小于重载什么的没有关系 你在尝试通过迭代器直接修改set内部数据,这是不允许的,如果要修改,需要先取得这份数据的拷贝,修改拷贝值后重新放进set内

64,654

社区成员

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

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