std :: less <> не работает с моей std :: map - PullRequest
4 голосов
/ 30 ноября 2011

Я хотел создать карту с моей собственной структурой 'Point2' в качестве ключа, однако я получаю ошибки, и я не знаю, что их вызывает, так как я объявил 'operator <' для структуры Point2. </p>

Код:

std::map<Point2, Prop*> m_Props_m;
std::map<Point2, Point2> m_Orders;

struct Point2
{
    unsigned int Point2::x;
    unsigned int Point2::y;

Point2& Point2::operator= (const Point2& b)
    {
        if (this != &b) {
            x = b.x;
            y = b.y;
        }
        return *this;
    }

    bool Point2::operator== (const Point2& b)
    {
        return ( x == b.x && y == b.y);
    }

    bool Point2::operator< (const Point2& b)
    {
        return ( x+y < b.x+b.y );
    }

    bool Point2::operator> (const Point2& b)
    {
        return ( x+y > b.x+b.y );
    }
};

Ошибка:

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(125): error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const Point2' (or there is no acceptable conversion)
1>c:\testing\project\point2.h(34): could be 'bool Point2::operator <(const Point2 &)'
1>while trying to match the argument list '(const Point2, const Point2)'
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(124) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
1>          with
1>          [
1>              _Ty=Point2
1>          ]

Кто-нибудь может понять, в чем причина проблемы?

Ответы [ 2 ]

9 голосов
/ 30 ноября 2011

std::map ожидает постоянную версию operator <:

// note the final const on this line:
bool Point2::operator< (const Point2& b) const
{
    return ( x+y < b.x+b.y );
}

Не имеет смысла иметь неконстантные версии operator==, operator>, они также должны быть const.

Как указывает ildjarn ниже, это явный случай, когда вы можете реализовать эти операторы как свободные функции вместо функций-членов. Как правило, вы должны предпочесть эти операторы как свободные функции, если они не нуждаются в в качестве функций-членов. Вот пример:

bool operator<(const Point2& lhs, const Point2& rhs)
{
    return (lhs.x + lhs.y) < (rhs.x + rhs.y);
}
3 голосов
/ 30 ноября 2011

operator< должен быть определен как const, фактически так же должны быть и другие операторы сравнения, и в целом любой метод, который не изменяет свой класс:

bool Point2::operator== (const Point2& b) const
{
    return ( x == b.x && y == b.y);
}

bool Point2::operator< (const Point2& b) const
{
    return ( x+y < b.x+b.y );
}

bool Point2::operator> (const Point2& b) const
{
    return ( x+y > b.x+b.y );
}
...