C++ 中多组对的奇怪行为

Strange behaviour of multiset of pairs in c++

本文关键字:C++      更新时间:2023-10-16

使用Cmp,我按对的第二个值对multiset进行排序。

问题 1:我没有使用set,因为我无法同时存储 {5,3} 和 {6,3},我不知道为什么,因为它们不同。

using pair_type = std::pair<int, int>;
struct Cmp
{
bool operator()(const pair_type& v1, const pair_type& v2) const
{ 
return v1.second < v2.second; 
}
};
int main()
{
multiset<pair_type,Cmp> m;
m.insert({1,1});
m.insert({2,1});
m.insert({3,2});
m.insert({4,2});
m.insert({5,3});
m.insert({6,3});
auto itr = m.find({6,3});
m.erase(itr);
}

问题 2m.erase也擦除 {5,3} 而不是 {6,3},即具有相同第二个值的第一对被擦除。事实上,m.find({6,3})返回 {5,3}。是什么原因造成的,如何解决这两个问题?

您明确地只比较 cmp 中对的第二个值:

return v1.second < v2.second;

您需要比较两者:

return v1 < v2;

或者干脆不添加比较器。

如果您不这样做,则查找将找到值为 {xxx, 3} 的任何项目,这就是您所看到的。如果进行此更改,则可以改用集合,因为值的比较方式会有所不同。

一个更技术性的解释:当您提供一个仅使用一对中的第二个值进行比较的自定义比较器时,容器无法区分 {5, 3} 和 {6, 3} - 您已经明确告诉它它们是相同的,因此搜索/相等不会按您想要的方式工作。

我没有使用 set,因为我无法同时存储 {5,3} 和 {6,3},我不知道为什么,因为它们是不同的。

你告诉布景他们是一样的。因为它们是相同的,所以它没有存储两者,因为它只存储每件事中的一个。

问题 2:m.erase 也会擦除 {5,3} 而不是 {6,3},即具有相同第二个值的第一对被擦除。

这是因为 m.find 找到 {5,3},然后你删除它找到的项目。

事实上,m.find({6,3}( 返回 {5,3}。是什么原因造成的,如何解决这两个问题?

好吧,你告诉它{5,3}和{6,3}是一回事。您搜索了一个值,它找到的值与您搜索的值相等。这就是搜索的作用。

如果你希望它不将这些值视为相同,那么你需要使用一个比较器,它不会说它们是相同的。

从多集的角度来看,你插入了一个 3,另一个 3,然后你搜索了 3,你抱怨它找到了前 3 而不是第二个 3。怎么知道你想要第二个?

相关文章:
  • 没有找到相关文章