带有自定义比较器的 C++ 映射未插入所有元素

C++ map with custom comparator is not inserting all elements

提问人:Vahe Margaryan 提问时间:8/28/2023 最后编辑:463035818_is_not_an_aiVahe Margaryan 更新时间:8/28/2023 访问量:64

问:

我有以下代码:

enum Type {
  OUTPUT = 1,
  INPUT = 2,
  INOUT = 3
};

std::vector<int> data = {INPUT, INOUT, OUTPUT, INPUT, OUTPUT, INPUT}

我的目标是将信息存储到键是索引,值是某个字符的中。我希望它以这样一种方式排序,即那些具有价值的索引将在开始时。std::map<int, char>datadataINPUT

我试图编写一个自定义比较器:

struct Comparator {
  bool operator()(int lhs, int rhs) {
    if (data[lhs] == INPUT && data[rhs] != INPUT) {
      return true;
    } else if (data[lhs] != INPUT && data[rhs] == INPUT) {
      return false;
    }

    return data[lhs] < data[rhs]
  }
};

但是对于以下代码

int main()
{
  std::map<int, char, Comparator> m;

  for (unsigned i = 0; i < data.size(); ++i) {
    m.insert( {i, 'a' + i} );
  }
}

我的地图值为

0 -> 'a'
2 -> 'c'
1 -> 'b'

我希望里面有 6 个元素,前三个是0 -> 'a', 3 -> 'd', 5 -> 'f'

C++ 比较器

评论

1赞 Louis Go 8/28/2023
你想要吗?std::multimap
0赞 Pepijn Kramer 8/28/2023
键必须是唯一的,并且您的比较运算符必须能够提出排序(现在无法做到)。因此,您可能需要一个由输入/输出和地址组合的密钥
1赞 463035818_is_not_an_ai 8/28/2023
你期待什么输出?
0赞 Vahe Margaryan 8/28/2023
我希望里面有 6 个元素,前三个是0 -> 'a', 3 -> 'd', 5 -> 'f'
0赞 Eljay 8/28/2023
执行插入时,可能需要考虑检查其返回值,以查看插入是否失败。

答:

0赞 Yksisarvinen 8/28/2023 #1

您根据存储的值进行排序,并且其中只存储了 3 个值,因此您在地图中最多只能获得 3 个值。data

您的排序应基于 和 而不是 /:lhsrhsdata[lhs]data[rhs]

struct Comparator {
  bool operator()(int lhs, int rhs) const /* note the const here */ {
    if (data[lhs] == INPUT && data[rhs] != INPUT) {
      return true;
    } else if (data[lhs] != INPUT && data[rhs] == INPUT) {
      return false;
    }

    // either both are INPUT or both are not,
    // so compare lhs and rhs, not the values in data
    return lhs < rhs; 
  }
};

在线查看

评论

0赞 Jarod42 8/28/2023
可能:或return std::pair(data[lhs] != INPUT, lhs) < std::pair(data[rhs] != INPUT, rhs);const auto proj = [&](int i){return std::pair(data[i] != INPUT, i); }; return proj(lhs) < proj(rhs);