std::map唯一 std::less<> 2D 点作为键的功能
std::map unique std::less<> function for a 2D point as key
嗯,经过四个小时的调试,尽管我很困惑,但我找到了问题的原因…
我正在制作一些程序,在std::map中保存一些点,并在我的窗口中渲染这些点。但奇怪的是,有些点没有出现在地图上。
std::map<Point2, Prop*> m_Props_m;
void AddProp(std::pair<Point2, Prop*> p)
{
m_Props_m.insert(p);
}
struct Point2
{
unsigned int Point2::x;
unsigned int Point2::y;
//--------
Point2::Point2()
:x(0)
,y(0)
{}
bool Point2::operator< (const Point2& b) const
{
return ( x+y < b.x+b.y );
}
bool Point2::operator> (const Point2& b) const
{
return ( x+y > b.x+b.y );
}
};
感谢上帝,我有一些二叉树的经验,所以我可以找到我的问题的原因。
假设我们有2个Point2。
Point2 a(0,1);
Point2 b(1,0);
可以看到,使用操作符<方法将返回false,操作符>也将返回false。因此,如果a已经在映射中,而插入b,则插入失败。
现在,这一切都很好,但我怎么能解决这个问题?有没有一种方法可以让二维点的小于算子允许我存储地图上的每个唯一点?
std::map
根本不使用operator>
,所以您不必担心。
要对多个字段(在本例中为两个)进行排序,请使用所谓的"字典排序",这意味着第一个字段最重要,第二个字段打破联系:
bool operator<(const Point2 &lhs, const Point2 &rhs) {
return (lhs.x < rhs.x) || ((lhs.x == rhs.x) && (lhs.y < rhs.y));
}
如果点的坐标之和相等,则比较函数认为点相等。例如,(2,5)等价于(3,4),因为2 + 5 = 3 + 4。在地图中已经有对应点的点不会出现
一个更好的办法是先比较x,如果两个点的x值相等,再比较y。
bool operator< (const Point2 &lhs, const Point2 &rhs) {
return (lhs.x < rhs.x) || ((lhs.x == rhs.x) && (lhs.y < rhs.y));
}
这应该能奏效:
bool Point2::operator< (const Point2& b) const
{
if (x<b.x) return true;
else if (!(b.x<x) && y<b.y) return true;
else return false;
}
std::map
只使用operator<
。如果!(a<b) && !(b<a)
, a
和b
是相等的(不等于等于),那么映射将只存储它们中的一个。未使用operator>
在其他情况下比较Point2可能没有意义,因此为了避免误解,我建议您为映射提供比较函数,并从类中删除operator<
。
bool mapLessPoint2(const Point2& a, const Point2& b);
std::map<Point2, Prop*, &mapLessPoint2> m_Props_m;
在我看来,操作符重载应该只在对给定类型有意义的情况下使用,并且2D空间中的一个点比2D空间中的另一个点大是不直观的。
相关文章:
- std ::功能作为默认参数的功能
- 复制std ::功能多么昂贵
- 将多种类型传递给STD ::功能C
- STD ::功能,字面类型和模板
- 使用STD ::功能时,编译器无法推断类型
- 调用STD ::功能,并带有变体类型列表
- STD ::功能的类型扣除额
- STD功能替换向量中的字节范围
- 如何管理STD ::功能的STD ::向量
- 绑定std ::功能错误
- 将成员函数和lambdas传递给std ::功能
- std ::功能和错误:无需匹配函数
- 如何通过C通过C API传递std ::功能
- 将std ::函数铸造到其他std ::功能并调用它
- 如何将std ::功能包装器转换为变异功能
- rvalue参考绑定到std ::功能类型的LVALUE
- lambdas不使用功能接受std ::功能
- 虚拟方法与std ::功能成员变量在性能方面
- sTD ::功能的替代方案,用于收集可可的功能
- 为什么不能将std :: stol转换为std ::功能对象