C++ std::带或不带标准布局的配对:安全地重新解释?

C++ std::带或不带标准布局的配对:安全地重新解释?,c++,stl,C++,Stl,如果两类A和B属于,并且B定义为 class B { // any methods A a; } 这样做是安全的 A a; B* b = reinterpret_cast<B*>(&a); A; B*B=重新解释铸件(&a); 如果现在将A替换为std::pair,这是否也适用于所有可能的T1、T2?据我所知,std::pair是标准布局,如果T1和T2都是标准布局,但如果它们不是,这会影响在这种情况下安全地重新解释的可能性吗 如果现在将A替换为std::pa

如果两类
A
B
属于,并且
B
定义为

class B {
  // any methods
  A a;
}
这样做是安全的

A a;
B* b = reinterpret_cast<B*>(&a);
A;
B*B=重新解释铸件(&a);

如果现在将
A
替换为
std::pair
,这是否也适用于所有可能的
T1、T2
?据我所知,
std::pair
是标准布局,如果
T1
T2
都是标准布局,但如果它们不是,这会影响在这种情况下安全地
重新解释
的可能性吗

如果现在将
A
替换为
std::pair
,这是否也适用于所有可能的
T1
T2

不,在这种特殊情况下,它甚至不起作用

在这种情况下,这会影响安全地重新解释投射的可能性吗

一点也不。在这两种情况下,强制转换都无效

您违反了非正式的严格别名规则。更具体地说,根据标准,您正在将指向对象的指针(此处
&a
,其中
a
是对象)投射到
B*
。任何试图取消引用
B*
的操作都将失败,因为您没有对象
B

你可能认为你有一个对象,但实际上,根据标准,你没有。发件人:

在隐式更改联合的活动成员([class.union])或创建临时对象([conv.rval]、[class.temporary])时,通过定义([basic.def])、新表达式创建对象

这些情况都不适用,因此如果您尝试使用“object”
b
,则会出现UB,而这不是一个


现在,您应该咨询一下您的实现,因为许多实现为像您的IIRC这样的构造提供了基本保证。

我认为您在这种有限(
std::is_standard_layout
)的情况下是可以的。Amiga OS过去经常做这种事情,这里有些含糊不清。子句中没有定义
std::pair
的任何内容明确说明如果
T1
T2
是标准布局类,则生成的
std::pair
是标准布局类。它只是将结果类松散地描述为
T1
T2
的“一对”。我可以看到这样的论点,即这种松散的实现,再加上对标准布局类的更明确定义,必然意味着生成的
std::pair
成为标准布局对。我想说这是实现定义的。好问题。@SamVarshavchik:好吧,我是这样假设的:
“如果T和Y都是标准布局,那么每个std::pair都是标准布局。”