创建一个坐标为键的std :: map

时间:2013-08-02 14:53:02

标签: c++ visual-c++ stdmap

似乎不可能创建一个坐标为键的std :: map。当两个坐标的(x + y + z)相同时,地图只会覆盖前一个坐标。例如:

map[Coordinate(1, 0, 0)] = object1;
map[Coordinate(0, 1, 0)] = object2;
map[Coordinate(0, 0, 1)] = object3;

这将导致有一个带有1个元素的std :: map,其中包含object3作为值,Coordinate(0, 0, 1)作为键。如何防止这种情况,它会包含所有值?

#pragma once

struct Coordinate {
    double x, y, z;
    Coordinate(double x, double y, double z) : x(x), y(y), z(z) {}

    bool operator<(const Coordinate& coord) const {
     if(x + y + z < coord.x + coord.y + coord.z)
        return true;
     return false;
    }

    bool operator==(const Coordinate& coord) const {
        if(x == coord.x && y == coord.y && z == coord.z)
            return true;
        return false;
    }

    inline bool isInRange(Coordinate coord, int range) const {
        if(pow(coord.x - this->x, 2) + pow(coord.y - this->y, 2) + pow(coord.z - this->z, 2) <= range*range)
            return true;
        return false;
    }
};

3 个答案:

答案 0 :(得分:8)

  

«std :: map是一个包含键值的有序关联容器   配对唯一键。使用比较对键进行排序   功能比较。 »来自cppreference

默认比较函数是std::less,它将使用运算符&lt;在Key个对象上。

因此,问题在于operator<的{​​{1}}:

Coordinate

bool operator<(const Coordinate& coord) const { if(x + y + z < coord.x + coord.y + coord.z) return true; return false; } 为false,但(1, 0, 0) < (0, 1, 0)也为false,因此就(0, 1, 0) < (1, 0, 0)而言,std::map

为了将(1, 0, 0) == (0, 1, 0)个对象用作Coordinate中的键,您需要找到符合您需求的正确严格弱排序标准(std::map)。

正如其他人所说,你可以使用std::tie(在C ++ 11中)首先比较operator<,然后x然后y这样的内容:< / p>

z

答案 1 :(得分:2)

您的运营商&lt;必须工作,以便所有可能的坐标可以稳定的顺序放置。如果添加值,则有几种坐标组合彼此无法区分。

试试这个

friend bool operator < (const Coordinate& left, const Coordinate& right)
{
    if (left.z < right.z)
    {
        return true;
    }
    else if (right.z < left.z)
    {
        return false;
    }
    else if (left.y < right.y)
    {
        return true;
    }
    else if (right.y < left.y)
    {
        return false;
    }
    else if (left.x < right.x)
    {
        return true;
    }
    else /* (right.x < left.x) */
    {
        return false;
    }
}

答案 2 :(得分:-1)

为了进行比较,如果std::mapa会将两个对象b!(a < b) && !(b < a)视为相同。你的operator<确实造成了这种含糊之处。首先插入(1, 0, 0)作为键。接下来,您将插入(0, 1, 0)并进行比较。但是,对于您拥有的运算符,(1, 0, 0) < (0, 1, 0)会返回false(0, 1, 0) < (1, 0, 0)也会返回,因此两个坐标都会映射到同一个键。