似乎不可能创建一个坐标为键的std :: map。当两个坐标的(x + y + z)相同时,地图只会覆盖前一个坐标。例如:
map[Coordinate(1, 0, 0)] = object1;
map[Coordinate(0, 1, 0)] = object2;
map[Coordinate(0, 0, 1)] = object3;
这将导致有一个带有1个元素的std :: map,其中包含object3
作为值,Coordinate(0, 0, 1)
作为键。如何防止这种情况,它会包含所有值?
#pragma once
struct Coordinate {
double x, y, z;
Coordinate(double x, double y, double z) : x(x), y(y), z(z) {}
bool operator<(const Coordinate& coord) const {
if(x + y + z < coord.x + coord.y + coord.z)
return true;
return false;
}
bool operator==(const Coordinate& coord) const {
if(x == coord.x && y == coord.y && z == coord.z)
return true;
return false;
}
inline bool isInRange(Coordinate coord, int range) const {
if(pow(coord.x - this->x, 2) + pow(coord.y - this->y, 2) + pow(coord.z - this->z, 2) <= range*range)
return true;
return false;
}
};
答案 0 :(得分:8)
«std :: map是一个包含键值的有序关联容器 配对唯一键。使用比较对键进行排序 功能比较。 »来自cppreference
默认比较函数是std::less
,它将使用运算符&lt;在Key
个对象上。
因此,问题在于operator<
的{{1}}:
Coordinate
bool operator<(const Coordinate& coord) const {
if(x + y + z < coord.x + coord.y + coord.z)
return true;
return false;
}
为false,但(1, 0, 0) < (0, 1, 0)
也为false,因此就(0, 1, 0) < (1, 0, 0)
而言,std::map
。
为了将(1, 0, 0) == (0, 1, 0)
个对象用作Coordinate
中的键,您需要找到符合您需求的正确严格弱排序标准(std::map
)。
正如其他人所说,你可以使用std::tie
(在C ++ 11中)首先比较operator<
,然后x
然后y
这样的内容:< / p>
z
答案 1 :(得分:2)
您的运营商&lt;必须工作,以便所有可能的坐标可以稳定的顺序放置。如果添加值,则有几种坐标组合彼此无法区分。
试试这个
friend bool operator < (const Coordinate& left, const Coordinate& right)
{
if (left.z < right.z)
{
return true;
}
else if (right.z < left.z)
{
return false;
}
else if (left.y < right.y)
{
return true;
}
else if (right.y < left.y)
{
return false;
}
else if (left.x < right.x)
{
return true;
}
else /* (right.x < left.x) */
{
return false;
}
}
答案 2 :(得分:-1)
为了进行比较,如果std::map
,a
会将两个对象b
和!(a < b) && !(b < a)
视为相同。你的operator<
确实造成了这种含糊之处。首先插入(1, 0, 0)
作为键。接下来,您将插入(0, 1, 0)
并进行比较。但是,对于您拥有的运算符,(1, 0, 0) < (0, 1, 0)
会返回false
,(0, 1, 0) < (1, 0, 0)
也会返回,因此两个坐标都会映射到同一个键。