假设我们有类模板 Wrapper
像这样:
template <class T>
struct Wrapper { T wrapped; };
reinterpret_cast
哪些类型安全之间Type
和一个 Wrapper<Type>
?没有任何?标准布局?全部?假设我们创建了其中一个(
Type
和 Wrapper<Type>
)的对象,并通过另一个读取和写入该对象。示例( live on godbolt.org ):void F1() {
std::stringstream ss;
ss << "Hello";
reinterpret_cast<Wrapper<std::stringstream>&>(ss).wrapped << " world";
}
void F2() {
Wrapper<std::stringstream> ss;
ss.wrapped << "Hello";
reinterpret_cast<std::stringstream&>(ss) << " world";
}
阅读 this answer 的评论这个领域在标准中似乎不是很明确。我认为所有编译器都会生成一个按预期工作的代码(即一种类型的值可以转换为另一种类型),但标准目前可能无法保证这一点。如果没有,问题就出现了:标准能否保证这些强制转换的定义明确的行为,或者在这种情况下保证任何事情是不可能/不切实际的?因为我很确定,这些类型转换实际上会起作用。
最佳答案
重新诠释 T
(那不是 Wrapper<T>
的成员)作为 Wrapper<T>
永远不允许(F1
示例)。
另一方面,我相信重新诠释 Wrapper<T>
如 T
允许用于标准布局类:(F2
示例)
Two objects a and b are pointer-interconvertible if:
— one is a standard-layout class object and the other is the first non-static data member of that object, or ...
就在下面:
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a
reinterpret_cast
. ...
请注意,虽然此规则是对称的,但它要求两个对象都实际存在。如果您有引用
T
指向Wrapper<T>
的成员,那么您可以将其重新解释为 Wrapper<T>
(反之亦然)。但是如果它指向一个 T
不是 Wrapper<T>
成员的对象,那么就是UB。免责声明:“不允许这样那样的重新解释”是指访问
reinterpret_cast
的结果。会导致UB。类型转换本身不应该导致 UB。
关于c++ - 在 Type 和 Wrapper<Type> 之间 reinterpret_cast 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62765714/