Yii*_*iin 5 c++ stl duplicate-data map
为什么我的程序使用STL映射在键已存在时插入值而不是更改现有值?
#include <iostream>
#include <map>
using namespace std;
struct CTest
{
int a, b, c;
CTest(int A, int B, int C) : a(A), b(B), c(C) {}
};
bool operator<(const CTest & l, const CTest & r)
{
if(l.a < r.a) return true;
else if(l.a > r.a) return false;
if(l.b < r.b) return true;
else if(l.b > r.b) return false;
if(l.c < r.c) return true;
else if(l.c > r.c) return false;
return true;
}
struct CTest2
{
bool operator<(const CTest2 & r) const
{
return q < r.q && w < r.w;
}
int q,w;
CTest2() : q(0), w(0) {}
CTest2(int Q, int W) : q(Q), w(W) {}
};
int main()
{
// map of maps
map<CTest, map<string, CTest2> > x;
x[CTest(1,1,1)]["lol"] = CTest2(1,2); // x[CTest(1,1,1)]["lol"] now stores CTest2(1,2)
x[CTest(1,1,1)]["lol"] = CTest2(3,4); // CTest2(1,2) must be changed to CTest2(3,4)
x[CTest(1,1,1)]["lol"] = CTest2(5,6); // now to CTest2(5,6)
x[CTest(2,1,0)]["ha"] = CTest2(11,12);
for(map<CTest, map<string, CTest2> >::iterator i = x.begin(); i != x.end(); ++i)
for(map<string, CTest2>::iterator j = i->second.begin(); j != i->second.end(); ++j)
cout << j->first << " " << j->second.q << " " << j->second.w << endl;
}
Run Code Online (Sandbox Code Playgroud)
运行此打印:
lol 3 4
lol 1 2
ha 11 12
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况,我该如何解决?
Naw*_*waz 13
其中比较函数std::map使用的元素进行排序必须坚持以严格的弱序.但是你的实现并没有这样做.根据您的实现,当所有成员(a,b,c)相等时,您的operator<回报true.换句话说,(1,1,1) < (1,1,1)回报true.是否有意义?没有.
一个简单的解决方法是:
bool operator<(const CTest & l, const CTest & r)
{
if(l.a < r.a) return true;
else if(l.a > r.a) return false;
if(l.b < r.b) return true;
else if(l.b > r.b) return false;
return l.c < r.c;
}
Run Code Online (Sandbox Code Playgroud)
那太冗长了.而不是<,如果你使用!=,上面将减少到这个:
bool operator<(const CTest & l, const CTest & r)
{
if(l.a != r.a) return l.a < r.a;
else if(l.b != r.b) return l.b < r.b;
return l.c < r.c;
}
Run Code Online (Sandbox Code Playgroud)
嗯,这仍然很冗长,你可以实现它:
bool operator<(const CTest & l, const CTest & r)
{
return std::tie(l.a,l.b,l.c) < std::tie(r.a,r.b,r.c);
}
Run Code Online (Sandbox Code Playgroud)
该std::tie函数返回std::tuple其operator<工具STRICK弱排序,所以采取的这一事实.