3

我在一个程序中使用 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任何人都可以为这种(明显的)行为提供解释吗?

4

1 回答 1

4

首先,这段代码并没有按照你的想法去做。保留()不会调整大小()。

vector<int> v;
v.reserve(100);
v[0] = 1;  //undefined
cout << v.size(); //prints 0

再做一次编辑:我意识到这实际上是“预期的”行为,因为在第一种情况下,v 和 v1 都是空向量,因为 Reserve 不会影响==、<= 等的语义。一旦您了解 Reserve 是有效的除了将段错误变成令人困惑的行为之外什么都不做,这应该是有道理的。我建议永远不要使用储备,直到您证明它会产生性能差异(过早的优化)。

我对 <= 和 => 的描述以及您可能在此处不需要的地图,但将其留作参考,因为它可能会影响您在此问题上的工作。

其次,地图不关心事物是否==。他们关心事物是否在两个方向上都 <= - 这个词是“等价的”。例如

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 <= foo2 && foo2 <= foo1) 那么 somemap.insert(makepair(foo1, 1)); somemap.find(foo2) 会找到 foo1,即使 foo1 != foo2 或 !(foo1 == foo2)。

其次,向量上的 <= 运算符是什么?它不是测试具有相同大小和逐点==。我认为每个向量都是“等效的”,这意味着 <= 在两个方向上,对于空向量,但我不确定 - 无论如何都要考虑这种行为,因为这就是问题所在。

于 2012-04-20T22:28:36.917 回答