std::map 不接受我的运算符<

cap*_*ain 3 c++ opencv c++11

我有一个或多或少带有自定义键类型(Point2ffrom OpenCV)的地图,因此需要编写我自己的operator<. 除了,我的operator<没有被接受。

通过键创建地图/访问元素:

using namespace cv;
void foo()
{
    map<Point2f, double> properties;

    properties[Point2f(0, 0)] = 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我的运营商:

using namespace cv;
bool operator<(Point2f lhs, Point2f rhs)
{
    return lhs.x == rhs.x ? lhs.y < rhs.y : lhs.x < rhs.x;
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用上面的键设置地图的值时,我的编译器给了我

/usr/include/c++/4.8/bits/stl_function.h|235|error: no match for ‘operator<’ (operand types are ‘const cv::Point_<float>’ and ‘const cv::Point_<float>’)|
Run Code Online (Sandbox Code Playgroud)

(gcc, IDE 代码::块)

我已经试过了

  • 准确指定类型 ( cv::Point_<float>)
  • 将运算符直接放在调用它的函数上方
  • 对传递给运算符的变量使用常量、引用或常量引用而不是值

没有任何效果,错误不断出现。为什么它会出现,我需要更改什么才能使其正常工作?

Pra*_*ian 5

修改评论中发布的示例,以便模拟Point2f类在cv命名空间内,就像原来一样,重现错误。

namespace cv
{
struct Point2f
{
    int x, y;
    Point2f(int v1, int v2) : x(v1), y(v2) {}
};
}
Run Code Online (Sandbox Code Playgroud)

现场演示

在上面的定义之后添加 using 指令没有区别,因为这using namespace cv意味着cv命名空间下的所有内容都带入当前范围,而不是自动将后面的所有内容添加到cv命名空间中

定义operator<如下,以便ADL能够找到它。

namespace cv
{
bool operator<(Point2f const& lhs, Point2f const& rhs) // pass by reference is not necessary
                                                       // but might as well
{
    std::cout << "calling custom operator <\n";
    return lhs.x == rhs.x ? lhs.y < rhs.y : lhs.x < rhs.x;
}
}
Run Code Online (Sandbox Code Playgroud)

现场演示


另一种选择是为Point2f对象定义一个比较器,以避免将运算符重载添加到其他人的命名空间。

struct Point2fLess
{
    bool operator()(Point2f const&lhs, Point2f const& rhs) const
    {
        std::cout << "calling custom operator <\n";
        return lhs.x == rhs.x ? lhs.y < rhs.y : lhs.x < rhs.x;
    }
};
Run Code Online (Sandbox Code Playgroud)

现在定义你map

std::map<Point2f, double, Point2fLess> properties;
Run Code Online (Sandbox Code Playgroud)

现场演示