要测量流的位置/偏移量/大小,标准指定了std::streampos
、std::streamoff
和std::streamsize
,但它们是实现定义的。
如何以安全和可移植的方式将这些类型转换为long long int
?(例如,测量文件大小并将其注入以长整型为参数的函数中)
好吧,就C++98/03而言,没有long long int
。所以我假设你在问C++11。
streamsize
和streamoff
必须是整数类型的typedef(streampos
不是整数,因此不会将其传递给任何需要long long
的对象)。由于积分类型是基本类型,它们只能由C++或编译器特定的定义来定义。
因此,唯一的问题是:这些typedefs是否比long long
大?所有的积分类型都可以转换为更大或大小相等的类型(尽管有符号/无符号,但这里的所有类型都是有符号的,所以没有问题)。但如果它更大。。。你打算怎么办?
假设您无法更改要"注入"的函数的签名(因为如果可以,就没有理由不将streamsize
作为参数类型,从而避免问题),那么您就没有任何选择。您的数据值大于函数的值。这里没有办法绕过它。
您可以对long long
执行static_cast以关闭编译器,但如果实际大小无法容纳long long
,这将没有帮助。
归根结底,这是一个棘手的问题。您有一个函数,它接受的参数对于您传递的内容来说可能太小了。您所能做的最多的事情就是通过static_assert
检测何时可能出现问题。类似这样的东西:
static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops.");
老实说,我并不担心。long long
很可能是编译器本机支持的最大整数大小。
只需将值传递给任何需要long-long的函数。std::streamoff
和std::streamsize
都是有符号积分类型,并且std::streampos
可以隐式转换为std::streamoff
。
edit:我想断言streamsize/streamoff不大于long long
不会有什么影响,以防有人提出__int128文件大小。
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是另一个岛屿。。。