Ошибка при перегрузке оператора <в sf:: Vector

Я хочу использовать std::map с sf::Vector2i класс, но по какой-то причине мне нужно overload < operator, Поскольку карта будет представлять собой 3x3 Сетка, я придумал это, чтобы отсортировать векторы:

inline bool operator <(sf::Vector2i l, sf::Vector2i r)
{
    if (l.x * 3 + l.y < r.x * 3 + r.y) return 1;
    return 0;
}

Но я все еще получаю ошибку C2678

не найден оператор, который принимает левый операнд типа 'const sf::Vector2i'

Я сделал то же самое с моим собственным векторным типом, и это сработало, так что является причиной этой ошибки?

Редактировать:

Эта перегрузка находится в отдельном .cpp файл. Я только что завернул эту перегрузку в пространство имен sf{} и это сработало. Почему это не работает, просто указав sf::Vector2i в параметрах?

2 ответа

Решение

Давайте начнем с:

Я хочу использовать std::map с sf::Vector2i класс, но по какой-то причине мне нужно перегрузить < оператор.

std::map упорядочивает его содержимое по ключам, что требует знания порядка ключей (предположительно sf::Vector2i). По умолчанию определение порядка клавиш дается operator <, Это означает, что карта вызывает operator<(const sf::Vector21&, const sf::Vector21&) определить, меньше ли один ключ, чем другой. Следовательно, этот оператор должен быть где-то определен.

Если вы не заинтересованы в этом заказе, вы можете попробовать unordered_map вместо.

Я только что завернул эту перегрузку в пространство имен sf{} и это сработало. Почему это не работает, просто указав sf::Vector2i в параметрах?

Это, вероятно, результат правил поиска для зависимых имен. Помните, что призыв к operator<? Это будет сделано где-то глубоко внутри шаблонов, а типы его аргументов зависят от параметров шаблона. Важным следствием этого является то, что компилятор будет искать объявления, видимые из определения шаблона (глубоко в заголовочных файлах), а также все, что будет найдено с помощью поиска, зависящего от аргумента (ADL). Ваша перегрузка не видна из определения шаблона (и не должна), поэтому ADL должен найти его. Однако оба аргумента находятся в пространстве имен. sf так ADL выглядит только в пространстве имен sf, Следовательно, компилятор может найти перегрузку в sf пространство имен, но не один в другом месте.

Это чаще встречается, когда аргументы находятся в std пространство имен, но должно применяться и здесь. (Некоторые из них для меня новы, поэтому я, возможно, испортил некоторые детали.) Основной вывод заключается в том, что попытка переопределить операторы, действующие только для классов в другом пространстве имен, часто дает сбой.

Хорошей новостью является то, что вы не застряли. std::map принимает более двух параметров шаблона. Третий позволяет указать, как должны сравниваться ключи. Читайте на предмете и посмотрите, как далеко вы можете получить.

Ваш оператор, на самом деле, не берет const Vector2i. Const важен!

Другие вопросы по тегам