[std::streampos] 可以隐式转换为 [size_t] 吗?
Can [std::streampos] be converted to [size_t] implicitly?
#include <fstream>
int main()
{
std::ifstream fin{ "" };
size_t n = fin.tellg(); // ok
}
代码编译正常。但是,根据 cppreference,我发现 fin.tellg()
是 std::fpos
的一种类型,它没有定义将自身隐式转换为 size_t
的能力。
有什么解释吗?
"OK" 在您的平台上。不一定在所有平台上都可以。这在实践中是否意义重大取决于具体情况。例如,在 32 位系统上,文件可能为 4GB 或更大,因此不适合 32 位 size_t
,其中 std::fpos
是一个 64 位值并且确实保存大小的文件。
如果 n
用于确定文件的长度或类似的东西,如果您错误判断总大小 - 覆盖旧数据,或者如果您加载文件然后保存它,可能会出现严重问题基于此,您将丢失部分或全部数据。
你说得对,它 returns 是 std::fpos
。现在让我们看看它是如何定义的:
template<class _Statetype>
class fpos {<...>}
fpos
也有一个转换运算符,用于转换为 streamoff
类型,即 "stream offset" 类型:
__CLR_OR_THIS_CALL operator streamoff() const
{ // return offset
return ((streamoff)(_Myoff + _FPOSOFF(_Fpos)));
}
在我的机器上 streamoff
恰好被定义为 typedef _Longlong streamoff;
,我相信它在您的机器上也是类似的。这就是为什么它可以转换为 type_t
,但是没有什么能阻止它大于 type_t
,所以要小心。
#include <fstream>
int main()
{
std::ifstream fin{ "" };
size_t n = fin.tellg(); // ok
}
代码编译正常。但是,根据 cppreference,我发现 fin.tellg()
是 std::fpos
的一种类型,它没有定义将自身隐式转换为 size_t
的能力。
有什么解释吗?
"OK" 在您的平台上。不一定在所有平台上都可以。这在实践中是否意义重大取决于具体情况。例如,在 32 位系统上,文件可能为 4GB 或更大,因此不适合 32 位 size_t
,其中 std::fpos
是一个 64 位值并且确实保存大小的文件。
如果 n
用于确定文件的长度或类似的东西,如果您错误判断总大小 - 覆盖旧数据,或者如果您加载文件然后保存它,可能会出现严重问题基于此,您将丢失部分或全部数据。
你说得对,它 returns 是 std::fpos
。现在让我们看看它是如何定义的:
template<class _Statetype>
class fpos {<...>}
fpos
也有一个转换运算符,用于转换为 streamoff
类型,即 "stream offset" 类型:
__CLR_OR_THIS_CALL operator streamoff() const
{ // return offset
return ((streamoff)(_Myoff + _FPOSOFF(_Fpos)));
}
在我的机器上 streamoff
恰好被定义为 typedef _Longlong streamoff;
,我相信它在您的机器上也是类似的。这就是为什么它可以转换为 type_t
,但是没有什么能阻止它大于 type_t
,所以要小心。