0

我有一组Vec3b来保存可能的 RGB 像素值。

std::set<cv::Vec3b> used_colors;


但行为怪异:

used_colors.insert(cv::Vec3b(100, 255, 255));

// this returns 1 although (100, 0, 0) is NOT in the set
used_colors.count(cv::Vec3b(100, 0, 0)); 


找到值 (100, 0, 0) 是因为集合中已经插入了其他以 100 开头的值。找不到其他值,例如 (80, 0, 0)。这显然是错误的奇怪行为。


我像这样实现了 < 比较运算符:

bool operator <(const cv::Vec3b &a, const cv::Vec3b &b) {
    if(a[0] < b[0])
        return true;

    if(a[0] > b[0]);
        return false;

    if(a[1] < b[1])
        return true;

    if(a[1] > b[1]);
        return false;

    if(a[2] < b[2])
        return true;

    if(a[2] > b[2]);
        return false;

    return false;
}
4

2 回答 2

4

operator<在几个语句之后,由于错误的分号,您被破坏了if

考虑输入a = Vec3b(100, 255, 255)b = Vec3b(100, 0, 0)。因为两者的R价值都是100测试使它

if(a[0] > b[0]);  // <-- notice the semicolon?

由于那个尾随分号,函数无条件返回false。由于同样的原因,比较b < a也返回false; 并set::count认为该元素已经存在。

去掉尾随的分号,您的比较运算符将按预期工作。


代替手动编写所有这些比较来进行字典排序,一种更简单、更不容易出错的方法是使用std::tie

bool operator<(const cv::Vec3b &a, const cv::Vec3b &b)
{
  return std::tie(a[0], a[1], a[2]) < std::tie(b[0], b[1], b[2]);
}
于 2013-05-12T05:08:28.313 回答
3

你的比较函数被塞满了,可能是因为你有;很多你的if语句之后。

即使这样,这也比它需要的复杂得多。std::tie使它成为一个单行:

bool operator <(const cv::Vec3b &a, const cv::Vec3b &b) 
{
    return std::tie(a[0], a[1], a[2]) < std::tie(b[0], b[1], b[2]); 
}
于 2013-05-12T05:09:41.247 回答