我想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
不起作用?
让我们从:
我想
sf::Vector2i
类中使用std::map
,但由于某种原因,我需要重载运算符<
。
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。常量很重要!