我在跨平台环境中与Qt合作。我们遇到了以下问题:在Windows上,int
和long int
都是32位整数;在64位MacOS和Linux上,int
为32位,long int
为64位(请参阅https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models)。
因此,跨平台库倾向于提供自己的固定位typedef。在Windows上,Qt将quint32
定义为unsigned int
,并且不使用unsigned long
整数。另一个库定义其Uint32
但是unsigned long
。因此,两者实际上都是32位无符号整数,但具有不同的原始数据类型。
现在,我们尝试使用为QDataStream
定义quint32
数据的Uint32
序列化,令我们惊讶(或不),Visual C ++抱怨{ {1}}运算符未被QDataStream
定义为真,因为Qt使用了几乎等效的unsigned long
。
好的,解决方法是提供
unsigned int
我的问题是:为什么我需要#ifdef Q_OS_WIN
inline QDataStream & operator >> (QDataStream & stream, Uint32 & value)
{ return stream >> reinterpret_cast<quint32 &>(value); }
inline QDataStream & operator << (QDataStream & stream, Uint32 value)
{ return stream << quint32(value); }
#endif // def Q_OS_WIN
?考虑到我的理解数据类型实际上是相同的,我觉得reinterpret_cast
更舒服。这是龙吗?
答案 0 :(得分:2)
int
和long
是不同的数据类型,即使它们恰好具有相同的属性。
由于严格的别名违规,您的operator>>
会导致未定义的行为;编写代码的正确方法是:
inline QDataStream & operator >> (QDataStream & stream, Uint32 & value)
{
quint32_t v;
stream >> v;
value = v;
return stream;
}
(注意:我假设QDataStream&gt;&gt;具有与C ++ 11 istream&gt;&gt;相同的属性,因为它在读取失败时将值设置为0
;如果没有,那么你&# 39; ll需要包含一个分支,以便在读取失败时不执行value = v;
。
您可以static_cast
使用operator<<
,因为它是值转换。实际上,您应该能够完全省略operator<<
。
您在问题中感叹的问题是构成自己的typedef而不是使用标准化类型的项目的必然结果。不幸的是,在项目决定转向标准化类型之前,这只是你必须要处理的事情。如果两者都使用了uint32_t
,那么这个问题就不存在了。