Я хочу использовать 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
no operator found which takes a left-hand operand of type 'const sf::Vector2i'
Я сделал то же самое со своим пользовательским векторным типом, и он сработал, так что же вызывает эту ошибку?
Редактировать:
Эта перегрузка находится в отдельном файле .cpp.
Я просто обернул эту перегрузку в пространство имен sf{}, и она сработала. Почему не работает просто указание sf::Vector2i в параметрах?
В дополнение к иммибису: определение оператора должно быть «видимым» там, где он используется. Обычный способ сделать это: определите его выше для функции, где он вам нужен, или определите его в файле заголовка, который является #included в файле, где он вам нужен.





Давайте начнем с:
I want to use
std::mapwithsf::Vector2iclass, but for some reason I need to overload<operator.
std::map упорядочивает свое содержимое по ключам, что требует знания порядка расположения ключей (предположительно sf::Vector2i). По умолчанию порядок расположения ключей определяется operator <. Это означает, что карта вызывает operator<(const sf::Vector21&, const sf::Vector21&), чтобы определить, меньше ли один ключ, чем другой. Следовательно, этот оператор должен быть где-то определен.
Если вас не интересует этот порядок, вы можете вместо этого попробовать unordered_map.
I just wrapped this overload in a namespace
sf{}and it worked. Why doesn't it work by just specifyingsf::Vector2iin the parameters?
Вероятно, это результат правила поиска для зависимых имен. Помните тот звонок в operator<? Это будет сделано где-то глубоко внутри шаблонов, а типы его аргументов зависят от параметров шаблона. Соответствующим следствием этого является то, что компилятор будет искать объявления, видимые из определения шаблона (глубоко в файлах заголовков), а также все, что найдено с помощью поиска, зависимого от аргументов (ADL). Ваша перегрузка не видна из определения шаблона (да и не должна), поэтому ее нужно будет найти с помощью ADL. Однако оба аргумента находятся в пространстве имен sf, поэтому ADL просматривает только пространство имен sf. Следовательно, компилятор может найти перегрузку в пространстве имен sf, но не где-либо еще.
Это чаще встречается, когда аргументы находятся в пространстве имен std, но должно применяться и здесь. (Кое-что из этого для меня в новинку, поэтому я мог перепутать некоторые детали.) Главный вывод заключается в том, что попытка переопределить операторы, действующие только на классы в другом пространстве имен, часто терпит неудачу.
Хорошая новость в том, что вы не застряли. std::map принимает более двух параметров шаблона. Третий позволяет указать, как нужно сравнивать ключи. Прочтите эту тему и посмотрите, как далеко вы можете продвинуться.
Фактически, ваш оператор не принимает константу Vector2i. Константа важна!
Почему в этом случае необходимо использовать const?
Извините, это не так. Я пропустил вашу правку, что он работает в пространстве имен sf. Я согласен с @JaMiT, что это, вероятно, проблема с поиском имени. Обычно бесплатные функции, операторы и т. д., Которые являются «частью» интерфейса класса, должны быть объявлены в том же пространстве имен. АДЛ сделает все остальное. Объявляя operator <, вы расширяете интерфейс Vector2i и должны поместить его в то же пространство имен.
const был бы важен, если бы параметр передавался по ссылке вместо значения. (Этот ответ тоже был одной из моих первых мыслей.) Кстати говоря, передача по ссылке const вместо value была бы хорошей идеей, @John.
@JaMiT Да, именно поэтому я в первую очередь опубликовал ответ. Я слишком быстро прочитал описание. Однако проголосовал за ваш ответ. Я думаю, это касается самого важного.
Надеюсь, я не произвел неправильного впечатления. Я не объяснял тебе, @ravnsgaard, столько, сколько объяснил случайному человеку, читающему эти комментарии. ;)
это заявлено в заголовке?