【问题标题】:How does std::less work if there is no explicit < operator?如果没有明确的 < 运算符,std::less 如何工作?
【发布时间】:2015-12-20 13:30:27
【问题描述】:

我想知道 std::less 如何在没有特定 operator &lt; 关联的键的映射中工作。

更具体地说,我正在使用两个库,每个库在 3D 空间中都有自己特定的点实现:

class Lib1Point
{
public:
    double x;
    double y;
    double z;
    // ctors, dtor and lots of fancy methods, but no further data members
};

class Lib2Point
{
private:
    double coords[3];

public:
    // lots of other fancy methods, but also no further data members
};

这两个类都没有定义operator &lt;

class SomeData;
std::map<Lib1Point, SomeData> m_pointData1;
std::map<Lib2Point, SomeData> m_pointData2;

这两个映射如何对它们的键进行排序?点会按相同的顺序排序吗?我可以以某种方式信任此顺序还是特定于编译器?如果我不能信任它,在没有访问点类源代码的情况下强制执行特定顺序的最简单方法是什么?

【问题讨论】:

  • 如果我没记错的话,这些容器根本不会对它们的键进行排序。除非您定义一个,否则没有明显的方法可以对 3D 点进行排序。
  • 您可以在std::map提供您自己的比较器

标签: c++ sorting dictionary key operator-overloading


【解决方案1】:

当您尝试将元素插入容器时,您会收到编译器错误。

int main()
{
    std::map<Lib1Point, SomeData> m_pointData1;
    std::map<Lib2Point, SomeData> m_pointData2;

    m_pointData1.insert({Lib1Point{}, 1});
}

Live Example.

给出错误

错误:二进制表达式的操作数无效('const Lib1Point' 和 'const Lib1Point')

      { return __x < __y; }
               ~~~ ^ ~~~

您可以为您的类型定义一个operator&lt;,或者编写一个自定义函数对象my_less,并将其作为第三个模板参数传递给std::map

#include <tuple>

struct Lib1Less {
    bool operator()(Lib1Point const& L, Lib1Point const& R) {
        return 
            std::forward_as_tuple(L.x, L.y, L.z) < 
            std::forward_as_tuple(R.x, R.y, R.z)
        ;
    }
};

int main()
{
    std::map<Lib1Point, SomeData, Lib1Less> m_pointData1;
    m_pointData1.insert({Lib1Point{1,2,3}, 1});
}

Live Example

【讨论】:

  • 感谢您的示例。也许我可以使用 tuple 作为我的地图的键类型。这肯定会改善相互之间的互动。
猜你喜欢
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多