Is there a way to find out if a class is the direct base of another class?

I am wondering if there is a way to find out if a class is the direct base of another class, i.e. in terms of type Boost a is_direct_base_of . As far as I can tell, Boost doesn't seem to support such functionality, which makes me think that this is not possible with the current C ++ standard.

The reason I want to do some verification checks on the two macros that are used for the reflection system to indicate that one class is derived from another, as in the example below.

header.h:

 #define BASE A #define DERIVED B class A {}; class B : public A { #include <rtti.h> }; 

rtti.h:

 // I want to check that the two macro are correct with a compile time assert Rtti<BASE, DERIVED> m_rtti; 

Although macros seem unnecessary in this simple example, rtti.h much more complicated in my real-world rtti.h .

One possible way would be to compare the size of this pointer with the size of this pointer passed to the base type, and somehow try to find out if it is the size of the base class itself or something else. (Yes, you're right, I don’t know how this will work!)

+4
source share
1 answer

I asked myself: "What C ++ constructs make a distinction between direct inheritance and indirect?" Let me remind you that C ++ constructors of derived types directly call constructors only for their direct bases. So, the code is as follows:

 Derived::Derived() : Base() {} 

Valid only if Base is a direct Derived base. And since you enter the rtti.h code into the body of Derived , you can endure the restriction that this method is only directly visible inside the derived class itself (i.e., it is not general, like the hypothetical type_traits::is_direct_base_of , but not necessary) .

So, since we probably don't want to interfere with the default constructors as such, but how do I add some special goals?

 #define BASE A #define DERIVED B struct rtti_tag {}; // empty type class A { protected: A(rtti_tag) { assert(false); } // never actually called }; #include <rtti.h> class B : public A { IS_DIRECT_BASE_OF(DERIVED, BASE); // fails to compile if not true }; 

rtti.h :

 #define IS_DIRECT_BASE_OF(_B_, _A_) _B_(rtti_tag tag) : _A_(tag) \ { assert(false); } // never actually called 

This code compiles for me with g ++ 4.2; if I insert a new class into the inheritance hierarchy, then the statement breaks and the compilation fails with what, in my opinion, is a fairly descriptive diagnosis:

 In constructor 'B::B(rtti_tag)': error: type 'A' is not a direct base of 'B' ... 
+11
source

Source: https://habr.com/ru/post/1301263/


All Articles