C++,静态检测具有不同地址的基类?
如果我有一个具有多个基类的派生类,则每个基类的每个 this 指针都将与派生对象的 this 指针不同,只有一个除外。 给定继承层次结构中的两种类型,我想在编译时检测它们是否共享相同的 this 指针。 像这样的东西应该可以工作,但不行:
BOOST_STATIC_ASSERT(static_cast<Base1*>((Derived *)0xDEADBEEF) == (Derived*)0xDEADBEEF);
因为它需要是一个“整数常量表达式”,并且根据标准只允许进行整数转换(这是愚蠢的,因为如果没有虚拟继承,它们只需要编译时信息正在使用中)。 尝试将结果作为整数模板参数传递时会出现同样的问题。
我能做的最好的事情就是在启动时检查,但我需要在编译期间提供信息(以使一些深入的模板黑客工作)。
If I have a derived class with multiple bases, each this pointer for each base will be different from that of the derived object's this pointer, except for one. Given two types in an inheritance hierarchy, I'd like to detect at compile time whether they share the same this pointer. Something like this should work, but doesn't:
BOOST_STATIC_ASSERT(static_cast<Base1*>((Derived *)0xDEADBEEF) == (Derived*)0xDEADBEEF);
Because it needs to be an 'integral constant expression' and only integer casts are allowed in those according to the standard (which is stupid, because they only need compile time information if no virtual inheritance is being used). The same problem occurs trying to pass the results as integer template parameters.
The best I've been able to do is check at startup, but I need the information during compile (to get some deep template hackery to work).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我不知道如何检查您不需要的内容,但请注意,在存在空基类的情况下,您的假设是错误的。 只要它们的类型不同,任意数量的它们都可以共享距对象开头的相同偏移量。
I don't know how to check what you wan't but note that your assumption is false in presence of empty base classes. Any number of them can share the same offset from the start of the object, as long as they are of different type.
我正在尝试解决这个完全相同的问题。 如果您知道基类布局开头的成员变量是什么,我有一个可以工作的实现。 例如,如果成员变量“x”存在于每个类的开头,则以下代码将产生特定基类布局相对于派生类布局的字节偏移量:offsetof(衍生,base2::x)。
对于以下情况:
<代码>
结构体base1 { char x[16]; };
结构体base2 { int x; };
结构派生:公共base1,公共base2 { int x; };
静态常量 int my_constant = offsetof(导出, base2::x);
编译
器将在我的架构 (x86_64) 上正确地将“16”分配给 my_constant。
困难在于,当您不知道基类布局开头的成员变量是什么时,要得到“16”。
I am trying to solve this exact same issue. I have an implementation that works if you know what member variable is at the beginning of the base class's layout. E.g. if member variable "x" exists at the start of each class, then the following code will work to yield the byte offset of a particular base class layout from the derived class layout: offsetof(derived, base2::x).
In the case of:
struct base1 { char x[16]; };
struct base2 { int x; };
struct derived : public base1, public base2 { int x; };
static const int my_constant = offsetof(derived, base2::x);
The compiler will properly assign "16" to my_constant on my architecture (x86_64).
The difficulty is to get "16" when you don't know what member variable is at the start of a base class's layout.
我什至不确定这个偏移量首先是一个常数。 您是否有其他暗示的规范措辞?
我同意,在没有虚拟继承的情况下,非常量偏移量将很难实现,并且启动毫无意义。 这不是重点。
I am not even sure that this offset is a constant in the first place. Do you have normative wording suggesting otherwise?
I'd agree that a non-const offset would be bloody hard to implement in the absence of virtual inheritance, and pointless to boot. That's besides the point.
类没有 this 指针 - 类的实例有,并且每个实例的 this 指针都是不同的,无论它们是如何派生的。
Classes do not have a this pointer - instances of classes do, and it will be different for each instance, no matter how they are derived.
如何使用
以下位置中记录的内容...
http: //www.boost.org/doc/libs/1_39_0/doc/html/boost_staticassert.html
http://www.boost.org/doc/libs/1_38_0/libs/type_traits/doc/html/boost_typetraits/reference/is_convertible.html
What about using
as documented in the following locations...
http://www.boost.org/doc/libs/1_39_0/doc/html/boost_staticassert.html
http://www.boost.org/doc/libs/1_38_0/libs/type_traits/doc/html/boost_typetraits/reference/is_convertible.html
我没有意识到编译器会在运行时插入此检查,但您的基本假设并不完全正确。 但可能不是您关心的方式:如果您碰巧从多个
sizeof(base class)==0
的基类继承,编译器可以使用空基类优化。 这将导致(基类*)(派生*)1==至少一个其他基类
。就像我说的,这可能不是您真正需要关心的事情。
I didn't realize that the compiler would insert this check at runtime, but your underlying assumption isn't entirely correct. Probably not in ways that you care about though: the compiler can use the Empty Base Class Optimization if you happen to inherit from more than one base class with
sizeof(base class)==0
. That would result in(base class *)(derived *)1==at least one other base class
.Like I said, this probably isn't something you would really need to care about.