带有自定义键的多图 - 比较功能

时间:2014-08-11 09:42:52

标签: c++ iterator multimap comparison-operators

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迭代器将对象返回

3 个答案:

答案 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。然后,您可以为rt1分别设置两个索引,并分别对这两个索引进行lower_boundupper_boundequal_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 < ca < b

,则不保证b < c

Ex:结合(r,t):a(3,5),b(4,6),c(5,5)

如果您的比较功能不符合上述条款,您可能会得到奇怪的结果。 (如果库不健壮,在某些情况下包括无限循环)

答案 2 :(得分:0)

如果rt由于if()子句中的&&而匹配,则您的比较函数将返回false。你是说||吗?将&&替换为||将为您提供有效的比较函数,该函数首先按r字段与t字段进行比较。

请注意std::pair已经有一个比较函数,它正是这样做的。

您的代码下面的文字虽然说明了:

  

基本上,如果其中一个属性匹配

,我需要认为对象相等

你不能这样做,因为它不会传递(因此你不会有严格的排序)。

if块的内部有另一个if肯定是真的,因为&&子句意味着双方都是真的。