问题描述
我在C ++ map.find()
中使用自定义比较器。不幸的是,#include <array>
#include <iostream>
#include <map>
using namespace std;
typedef struct DATA_t {
array<int,4> data;
} DATA_t;
struct DATA_cmp {
bool operator()(const DATA_t& a,const DATA_t& b) const {
for (int i = 0; i < a.data.size(); ++i)
if (a.data[i] < b.data[i]) return true;
return false;
}
};
int main(int argc,char** argv) {
map<DATA_t,int,DATA_cmp> index;
DATA_t data1 = {1,2,4,8};
DATA_t data2 = {1,3,5,7};
DATA_t data3 = {0,6,7,8};
DATA_t data4 = {0,1,2};
index[data1] = 1;
index[data2] = 2;
index[data3] = 3;
index[data4] = 4;
cout << "data1 " << (index.find(data1) == index.end() ? "not found" : "found") << endl;
cout << "data2 " << (index.find(data2) == index.end() ? "not found" : "found") << endl;
cout << "data3 " << (index.find(data3) == index.end() ? "not found" : "found") << endl;
cout << "data4 " << (index.find(data4) == index.end() ? "not found" : "found") << endl;
return 0;
}
通常在地图上找不到所需的条目。
复制此代码非常简单:
data1 found
data2 not found
data3 found
data4 found
输出应为所有“找到”的行,但我得到:
double lit = 0.1;
float x = (float)lit;
if ( ((double)x) == lit)
...
解决方法
您的比较功能不正确。考虑以下按键会发生什么:
{ 1,2,3,4 } // #1
{ 1,4 } // #2
现在比较#1
与#2
将返回true
,因为第二个索引较小(2 #2与#1
进行比较也将返回true
,因为第三个索引较小(2
这违反了密钥具有严格的弱排序的要求,即a < b
和b < a
不能同时为真。
您可以通过仅在以下数组上使用operator<
来解决此问题:
struct DATA_cmp {
bool operator()(const DATA_t& a,const DATA_t& b) const {
return a.data < b.data;
}
};
这里是demo。