我有一组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)。这显然是错误的怪异行为。
我实施了&lt;像这样的比较运算符:
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;
}
答案 0 :(得分: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]);
}
答案 1 :(得分: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]);
}