map.find看似随机返回map.end

问题描述

我在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 < bb < a不能同时为真。

您可以通过仅在以下数组上使用operator<来解决此问题:

struct DATA_cmp {
  bool operator()(const DATA_t& a,const DATA_t& b) const {
    return a.data < b.data;
  }
};

这里是demo