具有自定义键的Multimap -比较功能

multimap with custom keys - comparison function

本文关键字:比较 功能 Multimap 自定义      更新时间:2023-10-16
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,其关键是"绑定"对象。我面临的问题是lower_bound和upper_bound函数返回指向有效对象的相同迭代器。例如,(t1 = 1, r = 2)已经在映射中,当我尝试用(t1 = 1, r = 2)在映射中搜索它时,我得到的迭代器与upper_bound和lower_bound函数的返回值相同。

比较函数有什么问题吗?是否有一种方法来计算一个函数,我仍然可以确保对象是等效的,即使只有一个字段匹配?upper_bound迭代器不应该返回

之后的对象吗?

映射或multimap的比较器应该表示键集之间的严格弱排序关系。您的要求"如果两个对象的字段中只有一个匹配,则两个对象是等价的"不可能是这样的关系。以这三个键为例:

1: r=1, t1=10
2: r=1, t1=42
3: r=2, t1=42

显然,键1和键2是等价的,因为它们有相同的r。同样,2和3是等价的,因为它们有相同的t1。这意味着,1和3也必须是等价的,尽管它们没有匹配的字段。

作为推论,在这种情况下,所有可能的键必须是等价的,这意味着你根本没有任何排序,而multimap不是正确的方法。

对于您的情况,Boost。我想到了MultiIndex。然后,您可以为rt1设置两个单独的索引,并分别对这两个索引进行lower_bound, upper_boundequal_range搜索。

删除冗余代码后的比较函数可以重写为

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 < bb < c

不能保证a < c

例:绑定(r, t):一个(3、5)、b(4、6),c (5,5)

如果您的比较函数不遵循上述标准,您可能会得到奇怪的结果。(如果库不健壮,在某些情况下包括无限循环)

如果r s或t s因为if()子句中的&&而匹配,则比较函数将返回false。你是说||吗?将&&替换为||将为您提供一个有效的比较函数,该函数首先比较r字段,然后比较t字段。

请注意,std::pair已经有一个比较函数来做这个。

你的代码下面的文本虽然声明:

基本上,如果它们的一个属性匹配

,我需要认为对象相等

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

在你的if块内部有另一个if,它肯定为真,因为&&子句意味着两边都为真。