2011-03-12 49 views
3

With std::is_base_of<A,B>::value可以检查类A是否为基类 类B是否有可能向编译器查询类 B的所有基类,例如,类似base_classes_of<B>的东西返回包含所有基类B的std ::元组?如何在编译时查询类的所有基类?

是否有evtl. g ++中的非标准扩展可以实现这一点?

如果这是不可能的,有人知道为什么吗?这听起来像编译器应该有的一个相当基本的信息片段?

例子:

#include <type_traits> 
#include <tuple> 

struct A {}; 
struct B : A {}; 

static_assert(std::is_base_of<A, B>::value, "A is base of B"); 
static_assert(! std::is_base_of<B, A>::value, "but B is not base of A"); 

// now I am looking for something like 
// typedef base_classes_of<B>::type B_bases; 
// static_assert(std::is_same<B_bases, std::tuple<A>>::value, "all bases of B are: A"); 

int main() {} 
+0

不是真的有效。一个元组存储各种类型的值,而不是类型本身。 – 2011-03-12 07:26:56

+0

@Bo Persson我的意思是**元组类型**,当然。元组类型只存储类型的序列。上面的代码工作正常,如果你用'std :: tuple '手工填写'B_bases'。 – Lars 2011-03-12 08:29:30

+0

好吧,但这需要基类是具有默认构造函数的具体类。我认为这里会有很多角落案例。 :-( – 2011-03-12 08:38:49

回答

2

类似设施basesdirect_bases建议在 N2965
至于数据成员,由于数据成员可以是位域,他们的类型特征 有一些微妙之处。
另一方面,基类没有这样的问题。
我认为在某些情况下,像bases 一些编译时查询的需求,如中提到的激励N2965的示例。然而,不幸的是,目前的C++只是缺乏它,而据我所见,GCC和Clang-C++似乎暂时不提供类似的功能......

1

不,它不是在标准C++可能的,但你的预期目的,你可以只使用单个断言,一个是你必须存在于每个基类(或包装与一类型串)。

干杯&心连心,

1

这是不可能查询C++程序的基本类型给定类型的 - 这实际上是不可能的查询C++程序的任何东西....你可以写不过一个元谓语,它根据已知类型的类型列表(或参数包)查询已知类型(或反之亦然),并以编译类型生成真或假类型 - 它将递归地将std::is_base_of元谓语应用于所有类型在参数包中并累积结果。这是我能想到的唯一方法。我可以旋转一些代码,但我怀疑这是你真正想要的。真正的问题是:为什么你需要这样做,或者更好,为什么你需要在C++中?

+0

谢谢。如何对类型列表迭代地应用'std :: is_base_of'很简单。只是很好奇,为什么你可以为较弱的查询('is_base_of')编写一个metapredicate,而不是较强的查询('base_classes_of'),因为(a)编译器无论如何都有这个信息,(b)基类列表似乎是关于一个类的基本信息,我认为可能有一个比“没有人需要这些信息”更强有力的理由(尤其是你可以用Java等许多其他语言获得基类) – Lars 2011-03-12 13:09:47

+0

好吧,关键在于像Java这样的“语言”是一杯完全不同的茶,我把“语言”放在引号中,因为它不是使你能够做到的语言,而是运行时间, e书面。托管程序由程序流本身(翻译成中间语言)和程序使用的类型的元信息组成。当执行时,这些数据(Just In Time-)被编译成由底层平台执行的二进制代码...继续... – 2011-03-14 06:31:44

+0

...继续...二进制代码中没有元信息 - 它只是愚蠢地执行它被告知的事情。现在,C++程序立即编译成二进制代码 - 从中​​不能检索到这种信息。唯一拥有关于类型及其关系的信息的人是C++编译器,因此您可以在编译时查询此类关系。嗯,准确地说,这些“查询”是基于该语言的一些边界特征,所以我不会认为它们是这样的...... – 2011-03-14 06:34:19