重载运算符时出错<在sf :: Vector

时间:2018-06-15 01:31:24

标签: c++ templates overloading sfml

我想将std::mapsf::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 个答案:

答案 0 :(得分:2)

让我们从:

开始
  

我想将std::mapsf::Vector2i类一起使用,但由于某种原因,我需要重载<运算符。

A std::map按其键排列其内容,这需要知道如何订购密钥(大概是sf::Vector2i)。默认情况下,键的顺序定义由operator <给出。这意味着地图调用operator<(const sf::Vector21&, const sf::Vector21&)来确定一个键是否小于另一个键。因此,必须在某处定义此运算符。

如果您对此订单不感兴趣,可以尝试使用unordered_map

  

我只是将这个重载包装在命名空间sf{}中并且它有效。为什么不通过在参数中指定sf::Vector2i来实现它?

这可能是the lookup rules for dependent names的结果。还记得打电话给operator<吗?它将在模板内部的某处进行,其参数的类型取决于模板参数。这样做的相关结果是编译器将查找从模板定义(深入的头文件)中可见的声明,以及依赖于参数的查找(ADL)找到的任何声明。您的重载在模板定义中不可见(也不应该),因此ADL需要找到它。但是,参数都在命名空间sf中,因此ADL仅在命名空间sf中查找。因此,编译器可以在sf命名空间中找到重载,但在其他位置找不到。

当参数位于std命名空间时,这种情况更常见,但也适用于此处。 (其中一些对我来说是新的,所以我可能搞砸了一些细节。)主要的一点是,尝试覆盖仅在另一个命名空间中的类上操作的操作符通常会失败。

好消息是你没有陷入困境。 A std::map需要两个以上的模板参数。第三个允许您指定如何比较键。阅读主题并查看您可以获得的距离。

答案 1 :(得分:0)

实际上,您的操作员不会使用const Vector2i。 const非常重要!