这是我想做的:
const int64_t randomIntNumber = reinterpret_cast<int64_t> (randomUintNumber);
其中 randomUintNumber 的类型为 uint64_t
.
错误是(MSVC 2010):
error C2440: 'reinterpret_cast' : cannot convert from 'const uint64_t' to 'int64_t' 1> Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast
为什么不编译?两种类型都有相同的位长,这不是 reinterpret_cast 的用途吗?
最佳答案
因为这不是 reinterpret_cast
的用途。 reinterpret_cast
允许的所有转换都涉及指针或引用,但整数或枚举类型可以是 reinterpret_cast
自身的异常(exception)。这一切都在标准中定义,[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
的 typedef 的实现中,那么我的reinterpret_cast
没问题。与实现定义的超出范围值到有符号类型的转换一样,您会期望实现的明智之举是让它们对应有符号/无符号类型。因此,就像 static_cast
和隐式转换一样,您希望它可以在任何合理的实现中工作,但实际上并不能保证。
关于c++ - 为什么我不能将 uint 重新解释为 int?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14623266/