运算符使用自定义类重载C ++ STL映射

时间:2017-01-28 16:12:18

标签: c++ stl operator-overloading

我对在C ++中使用stl map有疑问。我知道使用自定义类的地图我需要重载"<"运算符使地图工作。但是我如何以有意义的方式定义它。例如,我有以下代码

#include <iostream>
#include <map>
using namespace std;

struct box{
    int e,s,w;
    box(): e(-1), s(-2), w(-3)
    {}

       bool operator< (const box& lhs) const
       {
           return e < lhs.e;
       }

};

int main() {
    // your code goes here
    map<box, int> hashtable;
    box b;
    hashtable[b] = 1;
    return 0;
}

这里我重载了&lt;操作员非常琐碎。我也可以按如下方式重载它

bool operator< (const box& lhs) const
{
    return w+s+e < lhs.e+lhs.s+lhs.w;
}

还有其他方法。所以我的问题是,这是否重载&lt;运算符,影响搜索,删除访问地图中元素的时间。我的意思是它是否影响地图的散列部分。如果是这样,重载的最佳方法是什么?运营商。

我唯一的动机是存储box和int对(参见main函数),这样我就可以在O(log(n))时间内访问它们。

更新

我认为有一个糟糕的比较器不会影响访问,删除地图的时间,而是影响地图中的键。例如,如果我的比较器是以下

bool operator< (const box& lhs) const
{
    return e < lhs.e;
}

现在让我说两个元组(e,s,w)为(1,2,3)和(1,3,4)。我想将它插入上面的地图。现在因为我有比较器,它只根据&#34; e&#34;的值来确定,它将拒绝第二个元组。所以最后地图将包含(1,2,3)而不是其他元组。

编写比较器的最佳方法是使用std::tie,正如@edgar在接受的答案中所建议的那样。

bool operator< (const box& lhs) const
{
    return std::tie(e,w,s) < std::tie(lhs.e,lhs.w,lhs.s);
}

在这两个元组中,即使元组具有不同的顺序,它们也是不同的。在我的问题中我有这个要求。例如(1,2,3)与(2,1,3)不同。我是否使用以下比较器

bool operator< (const box& lhs) const
{
    return e+w+s < lhs.e+lhs.w+lhs.s;
}

同样只有第一个元组才会成功,因为这两个元组都有相同的总和,所以再次不是一个好的比较器。

2 个答案:

答案 0 :(得分:4)

  

所以我的问题是,这是否超载&lt;操作员,影响   搜索,删除访问地图中元素的时间。

不,保证在对数时间内执行搜索,删除和访问元素。

  

我的意思是它会影响地图的散列部分。

std :: map 不是 std :: unordered_map ,因此这里没有散列。

  

如果是这样,重载的最佳方法是什么?操作

我认为现在的标准方法是使用directive

gcc

答案 1 :(得分:1)

std::map不是哈希映射,它是二叉树。

每次访问树时都会调用

operator<,每次查找步骤一次。显然,它的复杂性会影响性能(除了开销之外,std::map中的查询成本与operator<的成本成正比。

std::unordered_map是一个哈希映射。但为此,您需要实现std::hash<box>std::equal_to<box>(散列和平等函子)。在这种情况下不使用operator<