【发布时间】:2017-06-14 04:40:56
【问题描述】:
我对在 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;
}
在这里,我非常简单地重载了
bool operator< (const box& lhs) const
{
return w+s+e < lhs.e+lhs.s+lhs.w;
}
还有其他方法。所以我的问题是,
我在这里唯一的动机是存储成对的 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)。我想将它插入到上面的地图中。现在因为我有比较器,它仅根据“e”的值来确定,它会拒绝第二个元组。所以最后地图将包含 (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;
}
同样只有第一个元组会成功,因为这两个元组的总和相同,所以再次不是一个好的比较器。
【问题讨论】:
-
仅供参考,std::map 不是哈希表,也不使用哈希。为此,您需要 std::unordered_map。
-
对于像
e、w和s这样的变量名,很难理解operator<对于这个类的含义。 -
@PaulRooney,就我而言,我正在解决盒子堆叠问题。所以它是盒子的长度,呼吸,高度。如果有不同的元组,我想把它们放在树中,这通过 tie 解决。
标签: c++ stl operator-overloading