std::streampos、std::streamoff和std::streamsize是否为long-long-in

std::streampos, std::streamoff and std::streamsize to long long int?

本文关键字:std 是否 long-long-in streamsize streamoff streampos      更新时间:2023-10-16

要测量流的位置/偏移量/大小,标准指定了std::streamposstd::streamoffstd::streamsize,但它们是实现定义的。

如何以安全和可移植的方式将这些类型转换为long long int?(例如,测量文件大小并将其注入以长整型为参数的函数中)

好吧,就C++98/03而言,没有long long int。所以我假设你在问C++11。

streamsizestreamoff必须是整数类型的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::streamoffstd::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是另一个岛屿。。。

相关文章: