简体   繁体   English

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

[英]std::streampos, std::streamoff and std::streamsize to long long int?

To measure position/offsets/size of streams, the standard specify std::streampos , std::streamoff and std::streamsize , but they are implementation defined.为了测量流的位置/偏移量/大小,标准指定了std::streamposstd::streamoffstd::streamsize ,但它们是实现定义的。

How to convert these types to long long int in a secure and portable way ?如何以安全且可移植的方式将这些类型转换为long long int (for example to measure a file size and inject it in a function that take a long long int as argument) (例如测量文件大小并将其注入到以 long long int 作为参数的函数中)

Well, as far as C++98/03 is concerned, there is no long long int .好吧,就 C++98/03 而言,没有long long int So I'll assume you're asking about C++11.所以我假设你在问 C++11。

The streamsize and streamoff are required to be typedefs of an integral type ( streampos is not an integer, so you won't be passing that to anything that takes a long long ). streamsizestreamoff必须是整数类型的 typedef( streampos不是整数,因此您不会将其传递给任何需要long long东西)。 Since integral types are basic types, they can only be defined by either C++ or as a compiler-specific definition.由于整型是基本类型,它们只能由 C++ 或编译器特定的定义来定义。

Thus, the only question is this: are these typedefs larger than long long ?因此,唯一的问题是:在这些类型定义大于long long All integral types are convertible to a larger or equal-sized type (signed/unsigned notwithstanding, but all of the types here are signed, so no problem).所有整数类型都可以转换为更大或相同大小的类型(尽管有符号/无符号,但这里的所有类型都是有符号的,所以没问题)。 But if it is larger... what are you going to do about it?但如果它更大……你打算怎么办?

Assuming you can't change the signature of the function you are "injecting" it into (because if you could, there's no reason not to just take streamsize as the parameter type and thus avoid the problem), you don't have any options.假设你不能改变你“注入”它的函数的签名(因为如果可以的话,没有理由不只将streamsize作为参数类型从而避免这个问题),你没有任何选择. You have a data value that is larger than what the function takes.您的数据值大于函数所取的值。 There's no way of getting around it here.没有办法绕过它。

You can perform a static_cast into a long long to shut the compiler up, but this won't help if the actual size can't fit in a long long .您可以对long long执行 static_cast 以关闭编译器,但是如果实际大小不能放入long long ,这将无济于事。

Ultimately, this is an intractable problem.归根结底,这是一个棘手的问题。 You have a function that takes a parameter which is potentially too small for what you're passing.您有一个函数接受一个参数,该参数对于您传递的内容来说可能太小了。 The most you can do is detect when it might be a problem via a static_assert .您最多可以通过static_assert检测何时可能出现问题。 Something like this:像这样的东西:

static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops.");

To be honest, I wouldn't worry about it.老实说,我不会担心。 Odds are good that long long will be the largest integral size that your compiler natively supports.很可能long long将是您的编译器本机支持的最大整数大小。

Just pass the value to whatever function needs a long long.只需将值传递给需要 long long 的任何函数。 std::streamoff and std::streamsize are both signed integral types, and std::streampos is implicitly convertible to std::streamoff . std::streamoffstd::streamsize都是有符号整数类型,并且std::streampos可以隐式转换为std::streamoff

edit: I suppose an assert that streamsize/streamoff is not bigger than long long won't hurt, in case someone comes up with __int128 file sizes.编辑:我想断言 streamsize/streamoff 不大于long long不会受到伤害,以防有人提出 __int128 文件大小。

Short response for MINGW-64: std::streampos has a conversion operator to 64-bit-signed-integer type std::streamoff as MINGW-64 的简短响应: std::streampos有一个转换运算符到 64 位有符号整数类型std::streamoff作为

std::streampos pos = ...;
std::streamoff ofs = (std::streamoff) pos;

So, eg to find the length of a file you do not need to do more than opening an std::ifstream and evaluate ...因此,例如要查找文件的长度,您只需打开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;
}

... or think STL was another island ... ......或者认为STL是另一个岛屿......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM