我在一个程序中使用c ++ STL Map和Vector类,我有一个地图,它将一个向量作为指向整数的键。通常,当在地图中搜索值时,如果找不到该值,myMap.find()将返回myMap.end()。
当我尝试使用myVector.reserve(int)在我的向量中预先分配空间(以防止在我使用它时不断调整大小)时,我遇到了麻烦。出于某种原因,在我的地图中搜索我知道的向量不会返回myMap.end(),当我搜索的向量已分配空间时,无论我是否实际填充向量(示例1)。
但是,当向量不在地图中时,简单地将对象插入到我想要搜索的向量中将为我提供正确的myMap.end()位置(例2)。
示例1:
#include <map>
#include <vector>
#include <iostream>
using namespace std;
int main(){
vector<int> v, v1;
v.reserve(1);
v1.reserve(1);
v[0] = 1;
v1[0] = 2;
map<vector <int>, int> m;
m.insert(make_pair(v, 0));
cout << int(m.find(v1) == m.end());
}
返回0
示例2:
#include <map>
#include <vector>
#include <iostream>
using namespace std;
int main(){
vector<int> v, v1;
v.reserve(1);
v[0] = 1;
v1.push_back(5);
map<vector <int>, int> m;
m.insert(make_pair(v, 0));
cout << int(m.find(v1) == m.end());
}
返回1
我希望能够在向量中保留一定的空间,但似乎让地图按照图示工作的唯一方法是动态插入元素并动态调整向量的大小。它是否正确?有没有解决方法?任何人都可以为此(明显的)aberrant
行为提供解释吗?
答案 0 :(得分:4)
首先,这段代码不符合你的想法。 reserve()不会调整大小()。
vector<int> v;
v.reserve(100);
v[0] = 1; //undefined
cout << v.size(); //prints 0
还有一个编辑:我意识到这实际上是“预期的”行为,因为在第一种情况下,v和v1都是空向量,因为保留不影响==的语义,&lt; =等等。一旦你明白保留实际上什么都不做,只是把段错误变成混乱的行为,这应该是有道理的。我建议不要使用保留,直到你证明它会产生性能差异(过早优化)。
我对&lt; =和=&gt;的描述和地图你可能不需要在这里,但留待参考,因为它可能会影响你在这个问题上的工作。
其次,地图不关心事物是否==。他们关心事物是否在两个方向上都是&lt; =这个词是“等同的”。 e.g。
Foo foo1(1);
Foo foo2(2);
map<Foo, int> m;
m.insert(makepair(foo1, 1));
m.find(foo2) == m.end(); //will be true iff foo1 <= foo2 && foo2 <= foo1
//even if foo1 != foo2 or !(foo1 == foo2)
所以如果在某个类Foo中,if(foo1&lt; = foo2&amp;&amp; foo2&lt; = foo1)则somemap.insert(makepair(foo1,1)); somemap.find(foo2)即使foo1!= foo2或!(foo1 == foo2)也会找到foo1。
其次,你对矢量的&lt; =运算符是什么?它没有测试具有相同的大小和逐点==。我认为每个向量都是“等价的”,意思是&lt; =在两个方向上,对于空向量但我不确定 - 无论如何都要考虑这种行为,因为这就是问题所在。