std :: streampos,std :: streamoff和std :: streamsize到long long int?

时间:2012-10-08 00:29:55

标签: c++ file c++11 stream standards-compliance

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

如何以安全便携的方式将这些类型转换为long long int? (例如,测量文件大小并将其注入一个以long long int作为参数的函数)

3 个答案:

答案 0 :(得分:5)

嗯,就C ++ 98/03而言,不是 long long int。所以我假设你问的是C ++ 11。

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