2011-08-10 7 views
6

私は通常、そのようにベクトル反復処理:ベクトルの要素を反復処理するときのインデックス型は?

for (int i = 0; i < myVector.size(); i++) { 
    Element* e = myVector[i]; 
} 

をしかし、その後、コンパイラは、通常、私にこの警告与える:intはインデックスがあるべきタイプ、右でないのであれば

warning: C4018: '<' : signed/unsigned mismatch 

を? vector :: size()は "size_type"型のようですが、もっと意味のある型を使いたいと思います。なにか提案を?

+5

インデックスを使用する代わりに、イテレータを使用することを検討してください。 –

答えて

13

std::vector<T>::size_type を使用してください。その符号なし積分型。そのは通常と同じsize_tと同じです。

size_typesize_tの違いを知るために、このトピックを参照してください。

1.同様に、あなたはstd::string::size_typestd::list<T>::size_typestd::deque<T>::size_typestd::set<T>::size_type、というように使用することができます。ほとんどすべての標準コンテナは、size_typeと呼ばれる入れ子型を定義します。


一つは、あなたの代わりにインデックスイテレータを使用する必要があると主張することができます。しかし、繰り返しループが非常に幅広く水平になることがあることもわかります。

for(std::vector<std::vector<std::string> >::iterator it = v.begin(); it != v.end(); ++it) 
{ 
} 

これは表示されません。実際には時々刺激する。このような状況では、インデックスイテレータよりも好むプログラマもいます。

C++ 0xでは、イテレータがより慣用的になりました。今、あなたは面倒な構文にすることなくイテレータを使用することができます使用して、

for(auto it = v.begin(); it != v.end(); ++it) 
{ 
} 

あるいはさらに良いの範囲ベースのforループ:あなたのint型が署名されているので、コンパイラは警告を与える

for(auto & item : v) 
{ 
} 
2

size()は、size_t型のunsigned intを返します。あなたのintが負の場合に頭痛を引き起こす可能性があるので、このような不一致は望ましくありません。これを避けるには、size_tを使用します。

0

あなたはだけある反復のためにそれを使用した場合は、使用する場合があります:

typedef std::vector<Element*> ElementContainer; 
    ElementContainer myVector(3); 

    for (ElementContainer::const_iterator cit = myVector.begin();cit != myVector.end(); ++cit) 
    { 
     Element* e = *cit; 
    } 

これは、別の容器にvector<>から変更することに少しより堅牢であるという利点があります。

-1

unsignedをそのまま使用してください。size_tでは、含める適切なヘッダーが何であるかを覚えていません。vector<T>::size_typeを入力すると、あまりに多く入力することになります。すべての実用的な目的のために、彼らは同じことです、ちょうどtypedef edのダース。

+0

典型的な64ビットマシンでは、 'std :: size_t'と' unsigned'は同じものではありません。 –

+0

@David、64ビットマシンではどうなるでしょうか? 'size_t'ではなく' unsigned int'を使うと問題に遭遇できますか? –

+0

ベクトルの項目数が4294967295を超えている場合、 'unsigned int'を使って問題に遭遇します。あなたのアプリケーションがそれほど大きなベクトルを持つようになるかもしれないと思うなら、事前にこれをよく知っているでしょう。ほとんどの場合、 'std :: size_t'の代わりに' unsigned int'を使うことに問題はありません。 –

関連する問題