如果没有明确的 < 运算符, std::less 如何工作?

How does std::less work if there is no explicit < operator?

我想知道 std::less 如何在没有特定 operator < 关联的键的地图中工作。

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

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
};

class 和 operator < 都没有定义。

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

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

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

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

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

Live Example.

给出了错误

error: invalid operands to binary expression ('const Lib1Point' and 'const Lib1Point')

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

您可以为您的类型定义一个 operator<,或者编写一个自定义函数对象 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