C++中派生模板类与基类是否符合布局兼容要求?
结论
Base 和 Derived<int> 不符合C++标准定义的布局兼容要求,x86-64 gcc(trunk)下static_assert通过属于编译器自身的扩展实现,不代表标准层面的合规性。
标准条款解读
1. 布局兼容判定的前提
你提到的[class.mem]/16中关于布局兼容的规定,仅统计类自身直接声明的非静态数据成员,不包含继承自基类的成员:
两个standard-layout struct类型布局兼容的条件为:二者拥有相同数量的非静态数据成员,且按声明顺序对应的各非静态数据成员的类型均布局兼容。
按照这个规则:
Base自身直接声明了1个非静态数据成员int aDerived<int>自身没有声明任何非静态数据成员
二者的成员数量不匹配,天然不满足标准定义的布局兼容条件。
2. [class.derived]/8的补充说明
这条规定进一步明确了基类子对象的布局和独立的同类型对象布局没有绑定关系:
基类子对象的布局可能与同类型的最派生对象的布局不同。
也就是说即使实践中大部分编译器对简单单继承场景会把Derived<int>的基类子对象布局和独立Base对象布局保持一致,甚至允许你通过指针强转访问成员,也不代表两个类型本身符合布局兼容的标准定义。标准允许编译器对基类子对象做特殊布局调整,这种调整的可能性就决定了继承类和基类不可能满足标准层面的布局兼容要求。
编译器行为说明
gcc内置的__is_layout_compatible判断属于编译器扩展,它在实现时将继承来的成员也纳入了统计范围,所以针对你给出的简单场景会返回true,但这是厂商实现的自定义行为,不具备跨编译器的通用性,也不符合C++标准的要求。
内容的提问来源于stack exchange,提问作者sersh
相关产品推荐
相关产品推荐

