如果没有明确的< std :: less如何工作?运营商?

时间:2015-09-23 09:39:43

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

我想知道std::less如何在地图中使用没有与之关联的特定operator <的关键字。

更具体地说,我正在使用两个库,每个库都有自己在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 <

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

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

1 个答案:

答案 0 :(得分:5)

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

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<,也可以编写自定义函数对象my_less并将其作为第3个模板参数传递给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