size()
ベクトルの関数の結果を にキャストしても安全なようunsigned int
です。しかし、どうすれば確実に言えますか?私のドキュメントでは、 がどのようsize_type
に定義されているかが明確ではありません。
7 に答える
コンテナー サイズ (または内部に入力されたもの) の型を想定しないでください。
今日?
現時点での最善の解決策は、次を使用することです。
std::vector<T>::size_type
T はあなたのタイプです。例えば:
std::vector<std::string>::size_type i ;
std::vector<int>::size_type j ;
std::vector<std::vector<double> >::size_type k ;
(typedef を使用すると、これを読みやすくすることができます)
同じことが反復子にも当てはまり、STL コンテナーの「内部」にある他のすべての型にも当てはまります。
C++0x の後?
コンパイラが変数の型を見つけられるようになると、auto キーワードを使用できるようになります。例えば:
void doSomething(const std::vector<double> & p_aData)
{
std::vector<double>::size_type i = p_aData.size() ; // Old/Current way
auto j = p_aData.size() ; // New C++0x way, definition
decltype(p_aData.size()) k; // New C++0x way, declaration
}
編集:JFからの質問
unsigned int などを使用する既存のコードにコンテナーのサイズを渡す必要がある場合はどうすればよいでしょうか。– JF
これは、STL の使用に共通する問題です。何らかの作業を行わなければ、STL を使用することはできません。
最初の解決策は、常に STL 型を使用するようにコードを設計することです。例えば:
typedef std::vector<int>::size_type VIntSize ;
VIntSize getIndexOfSomeItem(const std::vector<int> p_aInt)
{
return /* the found value, or some kind of std::npos */
}
2 つ目は、static_cast を使用するか、値が目的の型の範囲外になった場合にアサートする関数を使用して、自分で変換を行うことです (「char」を使用するコードを目にすることがあります。決して 256 を超えることはありません」[記憶から引用])。
これはそれ自体が完全な質問になる可能性があると思います。
標準によると、確信が持てません。正確なタイプは、マシンによって異なります。ただし、コンパイラのヘッダー実装で定義を確認できます。
32 ビット システムでは安全ではないとは想像できませんが、64 ビットは問題になる可能性があります (int は 32 ビットのままであるため)。安全のために、変数を unsigned int ではなく vector<MyType>::size_type として宣言してみませんか?
C++ 標準では、 size_tが <cstddef> にあるとのみ述べられており、識別子は <stddef.h> に配置されます。Harbison & Steeleの私のコピーでは、 size_tの最小値と最大値を<stdint.h> に配置しています。これにより、受信者変数がプラットフォームに必要な大きさがわかります。
最善の策は、プラットフォームでポインターを保持するのに十分な大きさの整数型を使用することです。C99 では、これはintptr_tとuintptr_tであり、公式には <stdint.h> にあります。
size_tにキャストするのは常に安全です。unsigned intはほとんどの64ビットシステムでは十分ではなく、unsigned longでさえWindowsでは十分ではありません(ほとんどのUnixライクなシステムが使用するLP64モデルの代わりにLLP64モデルを使用します)。
システムの unsigned int が、ベクトル内にあるアイテムの数を保持するのに十分な大きさであることが確実である限り、安全であるはずです;-)
私は頭のてっぺんから考えているだけなので、これがうまくいくかどうかはわかりませんが、コンパイル時のアサーション (BOOST_STATIC_ASSERT()
または、ビルド時に C で式を ASSERT する方法を参照) が役立つ場合があります。何かのようなもの:
BOOST_STATIC_ASSERT( sizeof( unsigned int) >= sizeof( size_type));