首页 > 解决方案 > 自定义类 std::map 奇怪的行为

问题描述

在使用我创建为键的自定义类在地图中搜索键时,我遇到了一种奇怪的行为。

尽管它们存在于地图中,但它似乎找不到键。

有谁知道这是什么原因?

代码(可以在这里运行):

#include <iostream>
#include <map>

using namespace std;

typedef short int dimension;

class Point {
public:
    Point() : m_x(0), m_y(0) {}

    Point(const Point &other) : m_x(other.m_x), m_y(other.m_y) {};

    Point(dimension x, dimension y) : m_x(x), m_y(y) {}

    bool operator<(const Point &other) const {
        if (m_x < other.m_x) return true;
        return (m_y < other.m_y);
    }

private:
    dimension m_x;
    dimension m_y;
};


int main() {
    map<Point, bool> points = {{Point(0, 2), true},
                               {Point(1, 1), true},
                               {Point(2, 4), true}};

    cout << (points.find(((points.begin())->first)) == points.end()) << endl;
    cout << (points.find((next(points.begin()))->first) == points.end()) << endl;
    cout << (points.find((next(next(points.begin())))->first) == points.end()) << endl;

    cout << (points.find(Point(0, 2)) == points.end()) << endl;
    cout << (points.find(Point(1, 1)) == points.end()) << endl;
    cout << (points.find(Point(2, 4)) == points.end()) << endl;

    return 0;
}

输出:

1
0
0
0
1
0

标签: c++stdstdmap

解决方案


operator<的有缺陷:

bool operator<(const Point &other) const {
    if (m_x < other.m_x) return true;
    return (m_y < other.m_y);
}

例如

 {0, 3} < {1, 2}  -> true

 {1, 2} < {0,3}   -> true

operator<必须执行严格的弱排序。您忘记考虑(m_x > other.m_x)应该导致的情况false

避免此类问题的一个巧妙技巧是使用std::tie和利用std::tuple::operator<

bool operator<(const Point &other) const {
    return std::tie(m_x,m_y) < std::tie(other.m_x,other.m_y);
}

推荐阅读