问题描述
可以这样做吗?
struct compound_type {
int member;
};
void func()
{
compound_type foo {384};
int bar = sole_member_type_cast<int>(foo); // doesn't compile; there's no such thing
// reinterpret_cast wouldn't compile here
std::cout << bar << std::endl; // prints 384
}
我知道可以使用指针别名,但是这似乎是一个严格的别名问题。 (是吗?)还使用了联合,但是同样,您也不应该这样做,因为联合类型“一次只能容纳其非静态数据成员之一”(ref)。 / p>
在任何情况下,都会出现对齐或偏移问题吗?
解决方法
在具有一个公共非静态成员的结构与该成员之间进行转换的一种简单方法是使用结构化绑定:
auto [bar] = foo; // auto& to not copy
assert(bar == 384);
这也适用于非标准布局类型。例如,如果compound_type::member
是int&
或std::vector<int>
,则&foo
和&foo.member
将不再是指针可互换的。
是的,您可以这样做:
int bar = *reinterpret_cast<int*>(&foo);
由于compound_type
和int
的对象是pointer-inter-convertible,因此定义很明确。 foo
的地址与其第一个数据成员的地址int
相同,因此reinterpret_cast
的定义很明确。
正如@Remy Lebeau的评论中指出的那样,可以将转换简化为:
int bar = reinterpret_cast<int&>(foo);
这更容易阅读和编写。