use*_*168 4 c++ templates boost metaprogramming
我想知道是否有办法找出一个类是否是另一个类的直接基础,即在Boost类型特征术语中是一个is_direct_base_of
函数.据我所知,Boost似乎不支持这种功能,这使我认为使用当前的C++标准是不可能的.
我想要的原因是对两个用于反射系统的宏进行一些验证检查,以指定一个类是从另一个派生的,如下面的示例代码所示.
header.h:
#define BASE A
#define DERIVED B
class A {};
class B : public A
{
#include <rtti.h>
};
Run Code Online (Sandbox Code Playgroud)
rtti.h:
// I want to check that the two macro's are correct with a compile time assert
Rtti<BASE, DERIVED> m_rtti;
Run Code Online (Sandbox Code Playgroud)
虽然在这个简单的例子中宏看起来是不必要的,但在我的真实场景中,情况rtti.h
要复杂得多.
一种可能的途径是将this指针的大小与转换为基类型的this指针的大小进行比较,并以某种方式试图弄清楚它是否是基类本身的大小或其他东西.(是的,你是对的,我不知道那是怎么回事!)
Joh*_*nck 11
我问自己,"什么C++结构区分直接继承与间接继承?" 我们想到,派生类型的C++构造函数只直接调用构造函数来获取它们的直接基数.所以这样的代码:
Derived::Derived() : Base() {}
Run Code Online (Sandbox Code Playgroud)
仅在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
};
Run Code Online (Sandbox Code Playgroud)
rtti.h
:
#define IS_DIRECT_BASE_OF(_B_, _A_) _B_(rtti_tag tag) : _A_(tag) \
{ assert(false); } // never actually called
Run Code Online (Sandbox Code Playgroud)
这段代码用g ++ 4.2为我编译; 如果我在继承层次结构中插入一个新类,断言中断和编译失败,我认为这是一个合理的描述性诊断:
In constructor ‘B::B(rtti_tag)’:
error: type ‘A’ is not a direct base of ‘B’
...
Run Code Online (Sandbox Code Playgroud)