目前我有一个场景,我想检查将给定字符串写入文件流是否会使文件超出给定大小(这用于日志文件轮换)。现在,std::ofstream::tellp()
返回streampos
,但std::string::size()
返回size_t
。结果是,这不起作用:
out_stream.tellp() + string.size() < limit
因为这些类型显然存在operator +
的模糊重载。这引出了两个问题:
size_t
,streamsize
,streampos
,streamoff
)如何相互关联?什么时候可以安全地转换,以及可能存在的陷阱。我对这些类型感到困惑。我所知道的是它们是依赖于实现的,并且它们提供了某些保证(例如size_t
总是足够大以容纳大型对象的大小,该大小对象将适合编译应用程序的体系结构的内存。 ,但有关这些类型的互操作性的保证是什么(参见上面的示例,或将streamsize
与size_t
进行比较)?答案 0 :(得分:4)
您应该可以通过强制转换将结果从tellp转换为std::string::size_type
。
static_cast<std::string::size_type>(out_stream.tellp()) + string.size() < limit
编辑:这是安全的,因为您的流偏移永远不会是负数,并且会安全地转换为无符号值。
答案 1 :(得分:3)
真正的问题是:限制的类型是什么?通常的方式 测试是否还有空间通常是: limit - out_stream.tellp()&gt; = string.size() 但是你必须确保限制具有一种类型 可以减去out_stream.tellp()。
理论上,streampos不可转换,也不能与积分相媲美 类型,或转换为整数类型,它给出了重要意义 信息。它需要支持减法或比较 物。在实践中,我认为你不必过于担心 转换为现有的整体类型,并且是单调的(尽管如此) 也许在一些异国情调的大型机上...)。但你不能确定 使用它的算术会起作用,所以我可能更喜欢转换它 明确地给一个streamize(保证是一个有符号的整数 类型)。 (无论你如何解决问题,你都必须处理 事实上string.size()返回一个size_t,这是必需的 是无符号的,而溪流大小则需要签名。)
关于你的第二个问题: size_t是无符号整数类型的typedef,大到足以 指定任何可能对象的大小, streamsize是一个有符号整数类型的typedef,足够大 指定流中“对象”的大小, streamoff是一个能够指定的整数类型的typedef 一个字节在文件中的位置,和 streampos是fpos的typedef,其中 某种东西是可以用来维持状态的东西 多字节流的情况。 该标准对关系的要求很少 它们之间(以及它们中的少数几个在数学上是不可能的 实现),所以你几乎都是靠自己。
答案 2 :(得分:1)
我相信标准说streamsize
是特定于实现的,所以没有帮助。要获得实际答案,您可以查看typedef
编辑的标题。
考虑到size_t
可能是4个字节,而您的应用程序可能可以在长度超过4GB的流上运行,我相信您应该转换为已知的良好大小类型用于互操作的密闭解决方案。
当然,如果您知道(可能使用编译时断言)size_t
或streamsize
长度为8个字节,则可以直接使用该类型。如果你有一个长度不适合8个字节的流,那么你遇到的问题比转换成正确的类型更严重。
答案 3 :(得分:0)
如果您的尺码很大,那么无符号长就是最好的尺码。如果这还不够大,还有什么呢?