要测量流的位置/偏移/大小,标准指定std::streampos
,std::streamoff
和std::streamsize
,但它们是实现定义的。
如何以安全便携的方式将这些类型转换为long long int
? (例如,测量文件大小并将其注入一个以long long int作为参数的函数)
答案 0 :(得分:5)
嗯,就C ++ 98/03而言,不是 long long int
。所以我假设你问的是C ++ 11。
streamsize
和streamoff
必须是整数类型的typedef(streampos
不是整数,所以你不会将它传递给任何需要long long
的东西。 1}})。由于整数类型是基本类型,因此它们只能由C ++或编译器特定的定义来定义。
因此,唯一的问题是:这些typedef 大于而不是long long
吗?所有整数类型都可以转换为更大或相同大小的类型(尽管有符号/无符号,但这里的所有类型都是有符号的,所以没问题)。但如果它更大......你打算怎么做呢?
假设您无法更改函数的签名,而是将其“注入”(因为如果可以的话,没有理由不将streamsize
作为参数类型,从而避免出现问题),你没有任何选择。您的数据值大于函数所需的数据值。这里无法绕过它。
您可以在long long
中执行static_cast以关闭编译器,但如果实际大小不适合long long
,则无效。
最终,这是一个棘手的问题。你有一个函数,它接受的参数可能太小而不能传递。您可以做的最多是通过static_assert
检测何时可能出现问题。像这样:
static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops.");
说实话,我不担心。很可能long long
将是编译器本身支持的最大整数大小。
答案 1 :(得分:1)
只需将值传递给需要很长时间的任何函数。 std::streamoff
和std::streamsize
都是有符号整数类型,std::streampos
可隐式转换为std::streamoff
。
编辑:我认为如果有人提出__int128文件大小,则streamize / streamoff不大于long long
的断言不会受到影响。
答案 2 :(得分:-1)
MINGW-64 的简短响应:std::streampos
具有到 64 位有符号整数类型 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 是另一个岛屿...