因为这不是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 小于 263,则转换结果与输入具有相同的值。否则结果是实现定义的,但我希望所有具有int64_t 的已知实现都将其定义为做显而易见的事情:结果相当于输入模264。
如果您希望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 保证是相同大小的有符号类型和无符号类型,但它们实际上并不能保证是有符号的和标准整数类型的无符号版本。因此,此代码是否违反严格别名是特定于实现的。违反严格别名的代码具有未定义的行为。以下确实不违反了严格的别名,只要randomUintNumber中的位模式是long long值的有效表示,就可以了:
unsigned long long x = 0;
const long long y = reinterpret_cast<long long &>(x);
所以在int64_t 和uint64_t 是long long 和unsigned long long 的类型定义的实现中,我的reinterpret_cast 就可以了。与实现定义的超出范围值到有符号类型的转换一样,您期望实现的明智之举是使它们对应有符号/无符号类型。因此,就像static_cast 和隐式转换一样,您希望它可以在任何合理的实现中工作,但实际上并不能保证。