ストリームの位置/オフセット/サイズを測定するために、標準では、、およびを指定しますstd::streamposがstd::streamoff、std::streamsizeこれらは実装で定義されています。
long long intこれらのタイプを安全でポータブルな方法で変換するにはどうすればよいですか?(たとえば、ファイルサイズを測定し、引数としてlong long intをとる関数に挿入する場合)
ストリームの位置/オフセット/サイズを測定するために、標準では、、およびを指定しますstd::streamposがstd::streamoff、std::streamsizeこれらは実装で定義されています。
long long intこれらのタイプを安全でポータブルな方法で変換するにはどうすればよいですか?(たとえば、ファイルサイズを測定し、引数としてlong long intをとる関数に挿入する場合)
さて、C ++ 98/03に関する限り、ありません long long int。したがって、C++11について質問していると仮定します。
streamsizeとは、整数型のstreamofftypedefである必要があります(streampos整数ではないため、をとるものにそれを渡すことはありませんlong long)。整数型は基本型であるため、C++またはコンパイラ固有の定義としてのみ定義できます。
したがって、唯一の質問はこれです:これらのtypedefはlong long?すべての整数型は、より大きなまたは同じサイズの型に変換できます(符号付き/符号なしにもかかわらず、ここのすべての型は符号付きなので、問題ありません)。しかし、それがもっと大きい場合...あなたはそれについて何をするつもりですか?
「注入」している関数のシグネチャを変更できないと仮定すると(可能であればstreamsize、パラメータタイプとして取得しない理由がないため、問題を回避できます)、オプションはありません。関数が取るものよりも大きいデータ値があります。ここでそれを回避する方法はありません。
static_castをで実行しlong longてコンパイラをシャットダウンできますが、実際のサイズがに収まらない場合は役に立ちませんlong long。
結局、これは手に負えない問題です。渡すものに対して小さすぎる可能性のあるパラメーターを受け取る関数があります。できることのほとんどは、を介して問題が発生する可能性がある場合を検出することですstatic_assert。このようなもの:
static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops.");
正直、気になりません。オッズはlong long、コンパイラがネイティブにサポートする最大の整数サイズになる可能性があります。
長い間必要な関数に値を渡すだけです。std::streamoffとstd::streamsizeは両方とも符号付き整数型であり、std::streampos暗黙的にに変換可能std::streamoffです。
long long編集:誰かが__int128ファイルサイズを思いついた場合に備えて、streamsize /streamoffは害を及ぼさないよりも大きくないという主張をしていると思います。
MINGW-64の短い応答:std::streampos64ビット符号付き整数型への変換演算子がありますstd::streamoff。
std::streampos pos = ...;
std::streamoff ofs = (std::streamoff) pos;
したがって、たとえばファイルの長さを見つけるために、を開いて評価する以上のことをする必要はありませんstd::ifstream...
static unsigned long long getStreamSize(std::ifstream& is)
{
std::streampos savePos = is.tellg();
is.seekg(0, std::ios::end);
std::streampos endPos = is.tellg();
is.seekg(savePos);
return (std::streampos)endPos;
}
...またはSTLは別の島だったと思います...