我正在尝试使用地图来存储使用坐标x,y作为关键字的地图信息。我无法使用auto迭代器或map.find()正确迭代此映射。它只是不会返回正确的地图值。我正在使用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;
}
当我编译这段代码时,它给了我输出:
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)
它重复了第一个附加价值......我整天都被困住了。有任何想法吗?提前谢谢。
答案 0 :(得分:4)
你的operator <
完全搞砸了。
如果A的X坐标相等且Y坐标相等,则表示A小于B.所以(1,1)&lt; (2,2)是假的,但是(1,1)&lt; (1,1)是真的。难怪地图无法找到合适的条目。
特别是:
您需要确定点的实际顺序,并在operator <
中实现该顺序。例如,你可以说(a,b)&lt; (c,d)如果a&lt; c,或者a = = c且b bool operator < (const mapPoint &coord) const {
if (X < coord.X || (X == coord.X && Y < coord.Y)) {
return true;
} else {
return false;
}
}
答案 1 :(得分:3)
您的<
不符合严格的弱订单。因此,一旦放入地图,您的代码就会执行UB。
编写符合<
的简便方法是:
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);
}
我们将<
委托给tuple
的实施而没有副本和最大DRY(不要重复自己)。
我觉得手动做<
很简单,但几十年来一直容易出错。