3

With std::is_base_of<A,B>::value one can check if a class A is a base class of class B. Is it also possible to query the compiler for all base classes of a class B, e.g., something like base_classes_of<B> returning a std::tuple containing all base classes of B ?

Is there evtl. a non-standard extension in g++ that can accomplish this ?

If this is not possible at all, does anyone know why? It sounds like a rather fundamental piece of information the compiler easily should have available?

Example:

#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() {}
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
Lars
  • 2,616
  • 3
  • 21
  • 18
  • Not really working. A tuple stores values of various types, not the types themselves. – Bo Persson Mar 12 '11 at 07:26
  • @Bo Persson I mean the **tuple type**, of course. The tuple type stores just the sequence of types. The code above works fine, if you fill `B_bases` manually with `std::tuple`. – Lars Mar 12 '11 at 08:29
  • Ok, but that would require the base classes to be concrete classes with a default constructor. I think there would be a lot of corner cases here. :-( – Bo Persson Mar 12 '11 at 08:38
  • What do you want to do with this ? What you want to do is not possible non intrusively. If we know what you want to achieve, we could try and answer the underlying question. – Alexandre C. Mar 12 '11 at 10:35
  • You may notice that there is a big gap between what you can do (testing **if** a known class is a parent) and what you want to do (finding out **what** the base classes are). May-be to fill the gap, first figure out how to find the direct parent of a class (not that that is possible). – UncleBens Mar 12 '11 at 10:57
  • @UncleBens To write a predicate that iteratively collects all base classes once you have one that gives you the immediate ones is straight forward. But it looks like this is not possible either? So it would be interesting why? – Lars Mar 12 '11 at 13:12
  • @Bo Persson Tuple component types neither are limited to concrete classes nor to classes with default cstrs. You cannot instantiate such tuples then, but you can handle all kinds of type list with tuples. So this would be no obstacle here. – Lars Mar 12 '11 at 13:17
  • @Alexandre C. Thanks. See my answer to paul_71's answer below. – Lars Mar 12 '11 at 13:17
  • 1
    @Lars: Just for your information, `bases` and `direct_bases` were proposed in [N2965](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html). I think the demand on some compile-time query like `bases` exists in some situations. However, unfortunately, current C++ just lacks it. – Ise Wisteria Mar 12 '11 at 16:19
  • @Ise Wisteria Thanks, this is what I was looking for! Would you mind to post it as an answer so I can accept it? -- By the way, I tried to find out what happened to N2965? It seems not to be mentioned in any meeting minutes. – Lars Mar 12 '11 at 21:50
  • @Lars: Thanks, I'll try! Actually, I searched `bases/direct_bases` in current draft(N3242) too, however, they are missing somehow :-( – Ise Wisteria Mar 12 '11 at 23:40

3 Answers3

2

Similar facility bases and direct_bases were proposed in N2965.
As for data members, since data members can be bit-fields, their type traits have some subtleties.
On the other hand, base classes don't have such problems.
I think there is the demand on some compile-time query like bases in some situations, as mentioned in Motivating examples of N2965.
However, unfortunately, current C++ just lacks it, and as far as I saw, GCC and Clang-C++ seem not to provide similar facilities at the moment...

Ise Wisteria
  • 11,259
  • 2
  • 43
  • 26
1

No, it's not possible in standard C++, but for your intended purpose you can just use individual asserts, one for each base class you need to be present (or wrap that with a typelist).

Cheers & hth.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
1

It is not possible to query a C++ program for base types of a given type - it is actually not possible to query a C++ program for anything.... You could however write a meta-predicate, which queries a known type against a type list (or parameter pack) of known types (or vice-versa) and generates an true or false type at compile type - it would just recursively apply std::is_base_of meta predicate to all types in the parameter pack and accumulate the results. This is the only way I can think of. I could spin some code which does that but I doubt that is what you really want. The really question is: why do you need to do that, or better why do you need to that in C++?

Paul Michalik
  • 4,331
  • 16
  • 18
  • Thanks. How to apply `std::is_base_of` iteratively against a type list is straight forward. I just was curious why you can write a metapredicate for the weaker query (`is_base_of`), but not for the stronger one (`base_classes_of`), as (a) the compiler has this information anyway and (b) the list of base classes seems to be a fundamental piece of information about a class. I thought there might be a stronger reason than just "nobody ever needed this information" (esp. as you can get the base class(es) in many other languages such as Java). – Lars Mar 12 '11 at 13:09
  • Well the point is the "languages" like Java are a completely different cup of tea. I put "languages" into quotes because it's not the language which enables you to do that, it's the runtime on top of which these languages are written. Managed programs consist of the program flow itself (translated into an intermediate language) and the meta information about the types used by the program. When executed, this data is (Just In Time-) compiled into binary code which is executed by the underlying platform... continued ... – Paul Michalik Mar 14 '11 at 06:31
  • ...continued... There is no meta information left in the binary code - it just stupidly executes what it has been told to. Now comes the point: C++ programs are immediately compiled into binary code - from which no information of this kind can be retrieved. The only guy who has the information about types and their relationship is the C++ compiler, therefore you can query relationships of this kind at compile time. Hm, to be precise, these "queries" are based on some border features of the language so I would not really consider them as such... – Paul Michalik Mar 14 '11 at 06:34