没有主题解决了我在C ++中比较结构作为键映射的问题。
构造以下代码:
struct XYZ{
int x, y, z;
}
struct XYZComp{
bool operator()(const XYZ& l, const XYZ& r)
{
return ((l.x==r.x)&&(l.y==r.y)&&(l.z==r.z));
}
}
主要看起来像
int main()
{
map<XYZ, int, XYZComp> m;
m.insert(std::make_pair<XYZ,int>({1,2,3}, 1)); //ok
map<XYZ, int, XYZComp>::iterator it = m.find({1,0,3});
if(it!=m.end())
{
std::cout<<"Key exists in map";
}
else
{
m.insert(std::make_pair<XYZ,int>({1,0,3}, 1));
//never come here
//compiler thinks key already exists in map
}
return 0;
}
我刚试过没有XYZComparer但它仍然无效。
struct XYZ{
int x,y,z;
bool operator==(const XYZ& xyz)
{
return (x=xyz.x) && (y=xyz.y) && (z=xyz.z);
}
bool operator<(const XYZ& xyz)
{
return (x>xyz.x) && (y>xyz.y) && (z>xyz.z);
}
}
当我在地图中尝试现有项目时,如何解决这些结构XYZ的比较。
编辑:当至少有一个数字正确时,编译器认为结构是相同的。
答案 0 :(得分:0)
std::set
和std::map
的比较器应该是<
,而不是==
。二叉搜索树不仅需要知道对象是否相等;它需要给他们一个订单,因为数据结构已经排序。为您的对象重载<
运算符。
如果!comp(a, b) && !comp(b, a)
,对象被视为相等。 (Source)
如果重载<
,则无需将比较器显式提供给容器类型,因为默认情况下比较器为std::less
,它包裹<
运算符。
答案 1 :(得分:0)
std::map
使用<
订购商品。因此,struct XYZComp
需要提供用户定义的operator <
。
一个非常简单的解决方案是使用std::tie:
#include <tuple>
//..
struct XYZComp
{
int x,y,z;
bool operator < (const XYZComp& xyz)
{
return std::tie(x, y, z) < std::tie(xyz.x, xyz.y, xyz.z);
}
//...
};
std::tie
为你的struct元素引入了词典排序。
你可以通过级联&lt;来做同样的事情。比较,但随后代码变得更长,更容易出错:
struct XYZComp
{
int x,y,z;
bool operator < (const XYZComp& xyz)
{
if ( x < xyz.x )
return true;
if ( x == xyz.x && y < xyz.y )
return true;
if ( x == xyz.x && y == xyz.y )
return z < xyz.z;
return false;
}
//...
};