我想知道是否有办法找出一个类是否是另一个类的直接基础,即在Boost类型特征术语中是is_direct_base_of
函数。据我所知,Boost似乎不支持这种功能,这使我认为使用当前的C ++标准是不可能的。
我想要它的原因是对两个用于反射系统的宏进行一些验证检查,以指定一个类是从另一个派生的,如下面的示例代码所示。
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's are correct with a compile time assert
Rtti<BASE, DERIVED> m_rtti;
虽然在这个简单的例子中似乎没有宏,但在我的真实场景中,rtti.h
更加复杂。
一种可能的途径是将this指针的大小与转换为基类型的this指针的大小进行比较,并以某种方式试图弄清楚它是否是基类本身的大小或其他东西。 (是的,你是对的,我不知道那是怎么回事!)
答案 0 :(得分:11)
我问自己,“C ++结构区分直接继承与间接继承有什么区别?”我们想到,派生类型的C ++构造函数只直接调用构造函数来获取它们的直接基数。所以这样的代码:
Derived::Derived() : Base() {}
仅在Base
是Derived
的直接基础时才有效。并且由于您将rtti.h
的代码注入到Derived
的主体中,您可以容忍这种技术仅在派生类本身内直接可见的限制(即它不像假设那样通用) type_traits::is_direct_base_of
,但不一定是。)
因为我们可能不想乱用默认的构造函数本身,如何添加一些特殊的构造函数呢?
#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
这段代码用g ++ 4.2为我编译;如果我在继承层次结构中插入一个新类,断言中断和编译失败,我认为这是一个合理的描述性诊断:
In constructor ‘B::B(rtti_tag)’:
error: type ‘A’ is not a direct base of ‘B’
...