class Base1 {
int x;
};
class Base2 {
int y;
};
class Derive : public Base1, public Base2 {
public:
enum {
PTR_OFFSET = ((int) (Base2*)(Derive*)1) - 1,
};
};
但是编译器抱怨道
expected constant expression
每个人都知道表达式值4除了编译器,出了什么问题?
那么,如何在编译时获得偏移?
最佳答案 解决您在提供的代码中看到的立即编译器错误,(Base2 *)(Derive *)1很可能在编译时变为reinterpret_casts,并且DyP写为对问题的注释不是表达式所需的常量表达式枚举初始化.一些编译器,特别是GCC在这一点上并不严格,并且允许在常量表达式中使用reinterpret_cast,即使它被标准禁止(有关此进一步讨论,请参阅此GCC错误
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49171和
Constexpr pointer value的注释).
在编译时识别对象的布局是什么以及对其各个成员的偏移的更广泛的问题是没有明确定义的答案的棘手问题.该标准为实施者提供了很大的自由度来填充/打包对象的字段,通常不符合对齐考虑(有关摘要的详细信息,请参阅http://www.altdevblogaday.com/2013/05/03/cc-low-level-curriculum-part-11-inheritance/).虽然必须保持对象字段的相对顺序,但是在Derived实例中,并不需要在Derived实例的起始处的sizeof(x)偏移处;答案是编译器和目标体系结构相关.
总而言之,这种结构布局信息是在编译时确定的,至少在某些编译器上是可访问的(即使不是以便携式,符合标准的方式).在这个问题的答案中,C++ Compile-Time offsetof inside a template,Jesse Good提供了一些代码,在GCC上至少允许在编译时确定类型中的字段偏移量.遗憾的是,此代码不能为基类成员提供正确的偏移量.
您的问题的一个很好的解决方案等待在C中实现编译时反射支持,作为标准工作组的一部分正在进行的工作:https://groups.google.com/a/isocpp.org/forum/#!forum/reflection.