提问人:Josu Goñi 提问时间:1/12/2013 更新时间:1/12/2013 访问量:630
set::find() 找不到
set::find() doesn't find
问:
我对这段代码有问题(cubeBoxData是一组cubeBox):
cubeBox temp(bx,by,bz);
cubeBoxData.insert(temp);
set<cubeBox>::iterator i = cubeBoxData.find(temp);
const_cast<cubeBox&>(*i).addCube(x,y,z);
问题是 cubeBoxData.find(temp);找不到 temp,然后程序尝试调用 addCube() 失败,我不知道为什么,因为这段代码工作正常(只需更改第三行):
cubeBox temp(bx,by,bz);
cubeBoxData.insert(temp);
set<cubeBox>::iterator i = find(cubeBoxData.begin(),cubeBoxData.end(),temp);
const_cast<cubeBox&>(*i).addCube(x,y,z);
cubeBox 的运算符<为:
bool operator<(const cubeBox& c) const {
return x<c.x ? true : y<c.y ? true : z<c.z ? true : false;
}
addCube 不会改变 x、y 或 z。
我认为我的操作员<错了,我错过了一些愚蠢的东西,但我不知道它是什么。
答:
5赞
Mankarse
1/12/2013
#1
您定义的 不会建立严格的弱排序。例如,根据您的比较器,它既是 that 又是 that .因此,对 的所有操作都具有未定义的行为。operator<
{1,0,1} < {0,1,0}
{0,1,0} < {1,0,1}
set
您应该重写比较操作,以便它确实建立严格的弱排序。最简单的方法是使用:std::tuple
bool operator<(const cubeBox& c) const {
return std::tie(x,y,z) < std::tie(c.x,c.y,c.z);
}
评论
0赞
Josu Goñi
1/12/2013
谢谢,你是对的!问题是当 x>c.x 它应该返回 false 并停止检查时,我认为这应该更好:返回 x<c.x ?真 : x>c.x ?错误 : y<c.y ?真 : y>c.y ?错误:z<c.z ?true : 假;const cast 是因为“cubeBox”包含“立方体”的向量,也许我应该使用地图,但我没有改变短,我只是填充了那个向量。
1赞
Mankarse
1/12/2013
@JotaGe:为了正确起见,手动版本必须按如下方式工作:.return x == c.x ? (y == c.y ? (z < c.z) : (y < c.y)) : (x < c.x)
0赞
sbabbi
1/12/2013
#2
要整合前面的答案:
集合的元素是常量是有原因的,你不能只是const_cast和修改,因为这样做并不是告诉集合它应该重新排序你的元素。由于您的函数可能会更改元素的排序顺序,因此正确的方法是:addCube
cubeBox cpy = *i;
cubeBoxData.erase(i);
cpy.addCube(x,y,z);
cubeBoxData.insert(cpy);
评论
0赞
Josu Goñi
1/12/2013
正如我所写的,我没有改变顺序,x、y 和 z 仍然保持不变。问题出在我的.operator<
0赞
sbabbi
1/12/2013
@JotaGe很抱歉,所以错过了那句话
评论
a
b
a < b
b < a
const_cast