2012-04-20 8 views
3

私は、C++ STL MapクラスとVectorクラスを使用しています。整数を指すキーとしてのベクトル。通常、値をマップから検索する場合、値が見つからない場合、myMap.find()はmyMap.end()を返します。std :: vectorをstd :: vectorのキーとして使用すると、見つからない場合にend()が返されず、reserve()を使用します。

myVector.reserve(int)を使用して、ベクターでスペースを事前に割り当てようとすると、問題が発生します。何らかの理由で、私がベクトルを実際に埋めているかどうかにかかわらず、私が検索するベクトルにスペースが割り当てられているとmyMap.end()は返されません(例1)。

しかし、私が検索したいベクトルにオブジェクトを挿入するだけで、ベクトルがマップにない場合(例2)、適切なmyMap.end()の位置が得られます。

例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:私は量Oを確保することができるようにしたい1

#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()); 
} 

戻り値f空間を私のベクトルに入れていますが、地図を表示させるための唯一の方法は、その場で要素を挿入し、ベクトルのサイズを動的に変更することです。これは正しいです?回避策はありますか?誰もこれ(明らか)aberrantの動作の説明を提供できますか?

+1

'v [0] = 1;'と 'v1 [0] = 2;'は未定義の動作を引き起こします - 両方の 'vector <>'はまだ空です。 – ildjarn

+3

'reserve'と' resize'は2つの非常に異なるものです。あなたはおそらく 'resize(1)'を意味する – Cornstalks

+0

@Cornstalks - 私は実際にreserve()が私が呼んでいたかった機能だと考えましたが、resize()を変更すると、絶対にやった! cplusplus.comは、サイズ変更と予約の違いについて非常に複雑な説明を提供しています。 –

答えて

4

まず、このコードは、あなたが考えるとは限りません。 reserve()はサイズを変更しません()。

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

つ以上編集:私は、これは実際には最初のケースで以来、「期待される」動作で実現準備がないをしているので、VとV1の両方が空のベクトルで、= <、==のセマンティクスに影響を与えます予備が効果的に何もしていないことを理解したら、セグメンテーションを混乱させるような行動に変えてしまうのは理にかなっています。パフォーマンスの差があることが証明されるまで予備費を使用しないことをお勧めします(早すぎる最適化)。

私の説明は< =と=>ですが、ここには必要ないでしょうが、それでもこの問題の作業に影響を与える可能性がありますので参考にしてください。

第2に、マップは物事が==であるかどうか気にしません。彼らは物事が両方向で< =であるかどうかを気にします - これは "相当"です。例えば

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!= foo2または!(foo1 == foo2)であっても、foo1を検索します。

第2に、ベクトル上の< =演算子は何ですか?同じサイズを持ち、ポイントワイズであることのテストではありません。私はすべてのベクトルが "等価"であることを意味します。すなわち、空のベクトルに対して両方向で< =を意味しますが、私は確信していません - これは問題がある場所なので、

+0

'operator <'はベクトルに対して便利な方法で定義されています。 'lexicographical_compare'と同じです。 –

関連する問題