因为那不是reinterpret_cast
目的。所有允许的转换reinterpret_cast
都涉及指针或引用,但整数或枚举类型可以是reinterpret_cast
自身的例外。这一切都在标准中定义,[expr.reinterpret.cast]
.
我不确定你想在这里实现什么,但如果你想randomIntNumber
拥有与 相同的价值randomUintNumber
,那么做
const int64_t randomIntNumber = randomUintNumber;
如果这导致编译器警告,或者您只想更明确,那么:
const int64_t randomIntNumber = static_cast<int64_t>(randomUintNumber);
randomUintNumber
如果小于 2 63,则强制转换的结果与输入具有相同的值。否则结果是实现定义的,但我希望所有已知的实现int64_t
都会定义它来做显而易见的事情:结果相当于输入模 2 64。
如果你想randomIntNumber
拥有与 相同的位模式randomUintNumber
,那么你可以这样做:
int64_t tmp;
std::memcpy(&tmp, &randomUintNumber, sizeof(tmp));
const int64_t randomIntNumber = tmp;
由于int64_t
保证使用二进制补码表示,因此您希望实现定义static_cast
与 . 的超出范围值具有相同的结果uint64_t
。但它实际上并不能在标准 AFAIK 中得到保证。
即使randomUintNumber
是编译时常量,不幸的是这里randomIntNumber
不是编译时常量。但是,编译时常量有多“随机”?;-)
如果您需要解决这个问题,并且您不相信实现将超出范围的无符号值转换为有符号类型是明智的,那么就像这样:
const int64_t randomIntNumber =
randomUintNumber <= INT64_MAX ?
(int64_t) randomUintNumber :
(int64_t) (randomUintNumber - INT64_MAX - 1) + INT64_MIN;
现在,我赞成在可能的情况下编写真正可移植的代码,但即便如此,我认为这近乎偏执。
顺便说一句,你可能很想写这个:
const int64_t randomIntNumber = reinterpret_cast<int64_t&>(randomUintNumber);
或等效地:
const int64_t randomIntNumber = *reinterpret_cast<int64_t*>(&randomUintNumber);
这并不能完全保证工作,因为尽管它们存在int64_t
并且uint64_t
保证是相同大小的有符号类型和无符号类型,但它们实际上并不能保证是标准整数类型的有符号和无符号版本。因此,此代码是否违反严格别名是特定于实现的。违反严格别名的代码具有未定义的行为。以下不违反严格的别名,只要位模式 inrandomUintNumber
是 的值的有效表示,就可以了long long
:
unsigned long long x = 0;
const long long y = reinterpret_cast<long long &>(x);
因此,在and 是int64_t
anduint64_t
的 typedef 的实现long long
上unsigned long long
,我reinterpret_cast
的就可以了。与将超出范围的值转换为有符号类型的实现定义的转换一样,您会期望实现要做的明智的事情是使它们对应于有符号/无符号类型。因此,就像static_cast
隐式转换一样,您希望它可以在任何合理的实现中工作,但实际上并不能保证。