1

我正在尝试插入地图,其中键是一个类。我在我的类中重载了 operator< 函数,如下所示:

struct MyType
{
    int a, b, c;
    bool operator<(const MyType& Rhs) const
    {
       return (a<Rhs.a) || (b<Rhs.b) || (c<Rhs.c);
    }
}

但是对于某些(唯一)键,映射中的值会被覆盖。

多值键的首选 operator< 方法是什么?

我已经看到为使用元组的结构定义 operator<,但如果可以的话,我宁愿把它写下来。

4

4 回答 4

5

改为这样做:

return std::tie(a, b, c) < std::tie(Rhs.a, Rhs.b, Rhs.c);

你需要#include <tuple>

于 2012-12-14T14:17:19.497 回答
3

这个表达

(a<Rhs.a) || (b<Rhs.b) || (c<Rhs.c)

不会创建严格的弱排序:假设a > Rhs.a, 但是b < Rhs.b. 您的表达式返回true,但它应该是false:b仅当 s 相同时才应用于解决关系a,然后仅当s 和s 相同c时才应使用s 。ab

这导致以下“楼梯”表达式:

(a<Rhs.a) ||
(a==Rhs.a && b<Rhs.b) ||
(a==Rhs.a && b==Rhs.b && c<Rhs.c)

这是编写Kerrek SB 的回答中建议的表达式的漫长方式,我建议您使用它,因为它的可读性要好得多。

于 2012-12-14T14:27:13.650 回答
1

问题是,如果您实例化两个MyType,例如说,M1 = {1, 1, 2}并且M2 = {1, 2, 1}您遇到不幸的情况,M1 < M2 并且 M2 < M1

为了解决这个问题,您需要分配a b一些c意义/顺序:

struct MyType
{
    int a, b, c;
    bool operator<(const MyType& Rhs) const
    {
       if (a < Rhs.a) return true;
       if (a > Rhs.a) return false;
       if (b < Rhs.b) return true;
       if (b > Rhs.b) return false;
       return c < Rhs.c;
    }
}

(这是在 dasblinkenlight 的答案中编写表达式的一种不太理想的方法,但可能更容易理解)。

但是,一旦您了解了为什么需要这样做,您应该切换到 a tuple,这确实是样板代码。

于 2012-12-14T14:28:28.373 回答
0

如果您需要具有该类型键的映射并且不需要比较器,您可能需要使用 boost::unordered_map 并使用 boost::hash_combine 为您的类型定义哈希

于 2012-12-14T15:08:59.680 回答