这是我想做的事:
const int64_t randomIntNumber = reinterpret_cast<int64_t> (randomUintNumber);
其中randomUintNumber的类型为uint64_t
。
错误的是(2010 MSVC):
错误C2440:“的reinterpret_cast”:不能从“const的uint64_t中”转换到“的int64_t” 1>转换是有效的标准转换,这可以隐式或通过使用的static_cast,C样式转换或函数样式转换来执行
为什么不把它编译? 这两种类型具有相同的位长,是不是它的目的是什么reinterpret_cast的呢?
因为这不是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
都保证有符号类型和无符号类型的大小相同,但实际上并没有保证是一个标准的整数的符号和无符号版本类型。 因此,它是实现特定的代码是否违反严格别名。 违反严格别名代码未定义的行为。 以下不违反严格走样,并确定提供的位模式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
是OK。 并与外的范围的值符号类型实现定义的转换,你会期望 ,对于实现做明智的做法是让他们相应的有符号/无符号类型。 所以喜欢static_cast
和隐式转换,你希望它在任何合理的实施工作,但它实际上并没有保证。
使用static_cast
在这些情况下。 我想语言设计者在其所有的智慧,决定了它不被认为是“不安全足够的”保证一个reinterpret_cast
。
不它不是。 reinterpret_cast
大多旨在重新解释存储的现有比特作为不同类型的比它。 很多这些的解释是依赖于实现,标准列出了具体的(相当长在这里引用)的东西,可以用做列表reinterpret_cast
(主要是不同的指针/引用类型之间铸造),但是他说:
没有其他的转换可以明确使用的reinterpret_cast进行。
在你的情况,你可能想的类型转换,而不是现有的存储的重新解释。 使用static_cast
用于这一目的。
从C ++ 11标准(N3376)5.2.10.1:
可以明确使用的reinterpret_cast进行转换如下表所示。 没有其他的转换可以明确使用的reinterpret_cast进行。
如果类型是相同的,从整体式到允许的积分类型的唯一转换是逸岸。
其他涉及指针。
reinterpret_cast
用于重新解释对象的存储作为不同的对象。 如果你不想去通过规范的写法,你可以找到所有reinterpret_cast
可以做这里 。 一般来说,你可以记得你有一个指针类型的工作。
所以,如果你真的想重新诠释用于您的位uint64_t
作为int64_t
,然后执行以下操作:
int64_t randomIntNumber = reinterpret_cast<int64_t&> (randomUintNumber);
但是,如果你只是想转换对象,保持其价值,如果可能的...只是做编译器提出什么,使用static_cast
代替。
为什么不把它编译?
因为无论类型是一个指针。
这两种类型的具有相同的比特长度,
为什么会是怎么回事? 如果他们三分球,也许会的问题,他们指出,同样大小的东西,但他们没有指针。
是不是有什么的reinterpret_cast是为?
不, reinterpret_cast
是指针类型转换。 你可以做你想做的通过将一个&
演员和一个内*
外面。 这就是重新解释投是。