[英]Cant find inserted values in C++ map using struct as key
I'm trying to use a map to store map information using coordinates x,y as key. 我正在尝试使用地图以坐标x,y作为键来存储地图信息。 I cant iterate properly trough this map using the auto iterator or map.find(). 我无法使用自动迭代器或map.find()正确地遍历此地图。 It just wont return me the correct map value. 它只是不会返回我正确的地图值。 I'm using C++14, here is my chunk of code: 我正在使用C ++ 14,这是我的代码块:
#include <iostream>
#include <string>
#include <map>
#include <iterator>
#include <vector>
using namespace std;
struct mapPoint {
int X;
int Y;
bool operator < (const mapPoint &coord) const {
if (X == coord.X && Y == coord.Y) {
return true;
} else {
return false;
}
}
};
struct explorerNotes {
bool foundCoin;
int timesVisitedThisBlock;
vector<bool> unexploredEntrances; // 0 0 0 0 -> N S E W
explorerNotes():timesVisitedThisBlock(0),unexploredEntrances(4,false){}
};
int main() {
map<mapPoint, explorerNotes> explorerNotebook;
explorerNotes testNote1, testNote2, testNote3;
mapPoint testCoord1, testCoord2, testCoord3;
testNote1.foundCoin = true;
testNote1.timesVisitedThisBlock = 42;
testNote1.unexploredEntrances = {true, true, false, false};
testCoord1.X = 25;
testCoord1.Y = 3;
testNote2.foundCoin = false;
testNote2.timesVisitedThisBlock = 314;
testNote2.unexploredEntrances = {false, true, false, false};
testCoord2.X = 11;
testCoord2.Y = 2;
testNote3.foundCoin = true;
testNote3.timesVisitedThisBlock = 420;
testNote3.unexploredEntrances = {false, true, false, false};
testCoord3.X = 1;
testCoord3.Y = 1;
explorerNotebook.insert(pair<mapPoint, explorerNotes>(testCoord1, testNote1));
explorerNotebook.insert(pair<mapPoint, explorerNotes>(testCoord2, testNote2));
explorerNotebook.insert(pair<mapPoint, explorerNotes>(testCoord3, testNote3));
map<mapPoint, explorerNotes>::iterator p;
p = explorerNotebook.find(testCoord1);
cout << " testing 1:"
<< "\nfoundCoin: " << p->second.foundCoin
<< "\ntimesVisitedThisBlock: " << p->second.timesVisitedThisBlock
<< "\nunexploredEntrances: "<< "(" << p->second.unexploredEntrances[0] << "," << p->second.unexploredEntrances[1] << "," << p->second.unexploredEntrances[2] << "," <<p->second.unexploredEntrances[3] << ")" << endl;
map<mapPoint, explorerNotes>::iterator q;
q = explorerNotebook.find(testCoord2);
cout << " testing 2:"
<< "\nfoundCoin: " << q->second.foundCoin
<< "\ntimesVisitedThisBlock: " << q->second.timesVisitedThisBlock
<< "\nunexploredEntrances: "<< "(" << q->second.unexploredEntrances[0] << "," << q->second.unexploredEntrances[1] << "," << q->second.unexploredEntrances[2] << "," <<q->second.unexploredEntrances[3] << ")" << endl;
map<mapPoint, explorerNotes>::iterator r;
r = explorerNotebook.find(testCoord3);
cout << " testing 3:"
<< "\nfoundCoin: " << r->second.foundCoin
<< "\ntimesVisitedThisBlock: " << r->second.timesVisitedThisBlock
<< "\nunexploredEntrances: "<< "(" << r->second.unexploredEntrances[0] << "," << r->second.unexploredEntrances[1] << "," << r->second.unexploredEntrances[2] << "," <<r->second.unexploredEntrances[3] << ")" << endl;;
return 0;
}
When I compile this code it gave me the output: 当我编译这段代码时,它给了我输出:
testing 1:
foundCoin: 1
timesVisitedThisBlock: 42
unexploredEntrances: (1,1,0,0)
testing 2:
foundCoin: 1
timesVisitedThisBlock: 42
unexploredEntrances: (1,1,0,0)
testing 3:
foundCoin: 1
timesVisitedThisBlock: 42
unexploredEntrances: (1,1,0,0)
It just repeats the first added value...I'm stuck all day. 它只是重复第一个增加的价值...我整日呆滞。 Any ideas? 有任何想法吗? Thanks in advance. 提前致谢。
Your operator <
is completely messed up. 您的operator <
完全被搞砸了。
You are saying that A is less than B if its X coordinate is equal and its Y coordinate is equal. 您说的是,如果A的X坐标等于Y坐标,则A小于B。 So (1,1) < (2,2) is false, but (1,1) < (1,1) is true. 因此(1,1)<(2,2)为假,但(1,1)<(1,1)为真。 No wonder the map can't manage to find the right entry. 难怪地图无法找到正确的条目。
In particular: 尤其是:
You need to figure out an actual order for the points, and implement that order in operator <
. 您需要找出这些点的实际顺序,并在operator <
实现该顺序。 For example, you could say that (a,b) < (c,d) if a<c, or if a==c and b<d. 例如,如果a <c,或者a == c且b <d,则可以说(a,b)<(c,d)。 Then you get that (1,1) < (1,2) < (1,3) < (2,0) < (2,1) < ... 然后得到(1,1)<(1,2)<(1,3)<(2,0)<(2,1)<...
bool operator < (const mapPoint &coord) const {
if (X < coord.X || (X == coord.X && Y < coord.Y)) {
return true;
} else {
return false;
}
}
Your <
does not qualify as a strict weak ordering. 您的<
不符合严格的弱排序要求。 So your code does UB once put in the map. 因此,一旦您将代码放入地图,UB便会这样做。
The easy way to write a conforming <
is: 编写符合的<
的简单方法是:
friend auto mytie(const mapPoint& self){
return std::tie(self.X, self.Y);
}
friend bool operator<(const mapPoint& lhs, const mapPoint& rhs){
return mytie(lhs)<mytie(rhs);
}
Where we delegate <
to tuple
's implementation without copies and with maximal DRY (don't repeat yourself). 我们将<
委托给tuple
的实现,该实现不带副本且具有最大DRY(请勿重复)。
I find doing <
manually is easy, but error prone over the decades. 我发现手动执行<
很容易,但是数十年来容易出错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.