Ошибка при перегрузке оператора <в 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 важен!