0

Is there a way in C++ to check if a class has one or more base classes?

I am looking for a type trait that would return true for:

struct X
{
  int a;
  int b;
};

but return false for

struct Y : X
{
  int c;
  int d;
};

There doesn't seem to be any type trait for that in the standard library.

I need it to determine aggregate classes that can be decomposed in structured binding to the same number of arguments as they are initialized with in brace-initialization:

// class X is ok:
X x = {{}, {}};    // 2 arguments
auto [m1, m2] = x; // 2 arguments

// class Y is bad:
Y y = {{}, {}, {}}; // 3 arguments, because Y has base
auto [m1, m2] = y;  // 2 arguments

For thus filtered types I could determine how many members they can be decomposed into in structured binding by looking at how many numbers they can be maximally brace-initialized with. The latter can be determined with SFINAE tricks; the former cannot.

This in turn can be useful in a library like this one: https://apolukhin.github.io/magic_get/index.html

Andrzej
  • 5,027
  • 27
  • 36
  • Why would you need this information about a class? – n. m. could be an AI Oct 16 '20 at 19:46
  • 3
    Without compiler magic this isn't testable at all. I could not think of any thing a data type differ from another only while inheriting. – Klaus Oct 16 '20 at 19:47
  • 2
    Define virtual function like `bool is_base() { return true; }` with `return false;` in child classes. – i486 Oct 16 '20 at 19:51
  • I take it you want to do this without modifying the classes? If so, I don't think it's possible yet. Types don't carry that info around with them. – cigien Oct 16 '20 at 19:52
  • This is to be able to detect in C++20 aggregates that can be braced-initialized, and decomposed in structure binding with the same number of initializers/parameters. – Andrzej Oct 16 '20 at 19:53
  • 7
    Then your question is an XY problem. You should add that to the question, and make it the focus. Not that detecting whether a type has bases will help, since aggregates can have base classes from c++17. – cigien Oct 16 '20 at 19:57
  • 1
    if you know the base class then it is [`std::is_base_of`](https://en.cppreference.com/w/cpp/types/is_base_of). When you don't know the base, you cant. What would the information be good for? Your example with 2 / 3 arguments only works because you know both `X` and `Y` – 463035818_is_not_an_ai Oct 16 '20 at 20:13
  • Does this help? https://stackoverflow.com/questions/47882827/type-trait-for-aggregate-initializability-in-the-standard-library . – parktomatomi Oct 16 '20 at 20:24
  • Why not add the technique, or link to it, where you figure out the maximal arguments the aggregate can be initialized with? That's half the problem, and it might help with figuring out the other half. – cigien Oct 16 '20 at 20:30
  • Always test for the features you depend on, never on circumstantial evidence. If you need your classes to work with Boost.PFR then you should test for that. Or even better, don't test, and let the actual use of the classes with Boost.PFR be the test. I am sure the compiler can figure it out. – HAL9000 Oct 17 '20 at 00:54

0 Answers0