bool operator<(const Binding& b1, const Binding& b2)
{
if(b1.r != b2.r && b1.t1 != b2.t1)
{
if(b1.r != b2.r)
return b1.r < b2.r;
return b1.t1 < b2.t1;
}
return false;
}
我有一个比较功能,如上所述。基本上,如果其中一个属性匹配,我需要认为对象是相等的。我正在为我的multimap使用这个比较函数,其关键是&#39; Binding&#39;宾语。 我面临的问题是lower_bound和upper_bound函数返回指向有效对象的相同迭代器。例如(t1 = 1,r = 2)已经在地图中,当我尝试在地图中使用(t1 = 1,r = 2)搜索它时,我获得与upper_bound和lower_bound函数的返回值相同的迭代器
比较功能有问题吗?有没有办法计算一个函数,即使只有一个字段匹配,我仍然可以确保对象是等价的? 不应该使用upper_bound迭代器将对象返回
答案 0 :(得分:5)
地图或多图的比较器应该在该组键之间表示严格的弱排序关系。您的要求“如果只有一个字段匹配,则两个对象是等效的”不能是这样的关系。拿这三个键:
1: r=1, t1=10
2: r=1, t1=42
3: r=2, t1=42
显然,键1和键2是等价的,因为它们具有相同的r
。同样,2和3是相同的,因为t1
相同。这意味着,1和3也必须是等价的,尽管它们没有匹配的字段。
作为推论,所有可能的键在这些情况下必须是等价的,这意味着你根本没有任何排序,而且多图不是正确的方法。
对于您的情况,我想到了Boost.MultiIndex。然后,您可以为r
和t1
分别设置两个索引,并分别对这两个索引进行lower_bound
,upper_bound
和equal_range
次搜索。
答案 1 :(得分:2)
删除冗余代码后的比较功能可以重写为
bool operator<(const Binding& b1, const Binding& b2)
{
if(b1.r != b2.r && b1.t1 != b2.t1)
{
//if(b1.r != b2.r) // always true
return b1.r < b2.r;
//return b1.t1 < b2.t1; // Never reached
}
return false;
}
或者通过de-morgan法律
bool operator<(const Binding& b1, const Binding& b2)
{
if(b1.r == b2.r || b1.t1 == b2.t1) return false;
else return b1.r < b2.r;
}
如果a < c
和a < b
b < c
Ex:结合(r,t):a(3,5),b(4,6),c(5,5)
如果您的比较功能不符合上述条款,您可能会得到奇怪的结果。 (如果库不健壮,在某些情况下包括无限循环)
答案 2 :(得分:0)
如果r
或t
由于if()子句中的&&
而匹配,则您的比较函数将返回false。你是说||
吗?将&&
替换为||
将为您提供有效的比较函数,该函数首先按r
字段与t
字段进行比较。
请注意std::pair
已经有一个比较函数,它正是这样做的。
您的代码下面的文字虽然说明了:
基本上,如果其中一个属性匹配
,我需要认为对象相等
你不能这样做,因为它不会传递(因此你不会有严格的排序)。
if
块的内部有另一个if
肯定是真的,因为&&
子句意味着双方都是真的。