简体   繁体   English

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

[英]std::map does not accept my operator<

I have a map with a more or less custom Key-Type ( Point2f from OpenCV ) and thus need to write my own operator< . 我有一个或多或少的自定义Key-Type(来自OpenCV Point2f )的地图,因此需要编写我自己的operator< Except, my operator< doesn't get accepted. 除此之外,我的operator<未被接受。

Creation of the Map/Accessing an element by key: 按键创建Map /访问元素:

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

    properties[Point2f(0, 0)] = 0;
}

and this is my operator: 这是我的经营者:

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

but when I try to set a value of the map using a key like above, my compiler gives me 但是当我尝试使用上面的键设置地图的值时,我的编译器给了我

/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>’)|

(gcc, IDE Code::Blocks) (gcc,IDE Code :: Blocks)

I already tried 我已经试过了

  • specifying the type exactly ( cv::Point_<float> ) 准确指定类型( cv::Point_<float>
  • putting the operator directly above the function calling it 将操作符直接放在调用它的函数上方
  • using const, reference or const reference for the variables passed to the operator instead of values 对传递给运算符的变量使用const,reference或const引用而不是值

Nothing worked, the error keeps coming. 没有任何效果,错误不断涌现。 Why does it appear and what do I need to change to make it work? 它为什么会出现,我需要做些什么才能让它发挥作用?

Adapting the example posted in the comments, so that the mock Point2f class is within the cv namespace, as the original is, reproduces the error. 调整注释中发布的示例,以便模拟Point2f类在cv名称空间内,与原始版本一样,重现错误。

namespace cv
{
struct Point2f
{
    int x, y;
    Point2f(int v1, int v2) : x(v1), y(v2) {}
};
}

Live demo 现场演示

Adding a using directive following the definition above makes no difference because using namespace cv means bring everything under the cv namespace into the current scope , not everything that follows automatically gets added to the cv namespace . 按照上面的定义添加using指令没有区别,因为using namespace cv意味着cv命名空间下的所有内容都放到当前作用域中 ,而不是随后的所有内容都会自动添加到cv名称空间中

Define your operator< as follows so that ADL is able to find it. 定义您的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;
}
}

Live demo 现场演示


Another option, to avoid adding operator overloads to someone else's namespace, is to define a comparator for Point2f objects. 另一个选项是避免将操作符重载添加到其他人的命名空间,这是为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;
    }
};

Now define your map as 现在将map定义为

std::map<Point2f, double, Point2fLess> properties;

Live demo 现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM