2

I was looking for a way to get a tuple pack of all the inherited classes, couldn't find one.

Intend: I need to statically assert if a class inherits from a template base class. Template parameter is to be deduced from a specialization of a base template, given that I can deduce it's typename in the first place. Private inheritance.

Can this be done at all?

class Inherited : ClassA, ClassB ..., Class N
{};

//Expected usage
templ_traits<Inherited>::bases_tuple;
templ_traits<Inherited>::bases_count;
Sergey Kolesnik
  • 3,009
  • 1
  • 8
  • 28
  • 1
    "*Can this be done at all?*" No more than you could get a tuple of the types of all class data members. What you're talking about is ultimately reflection, which is not a thing C++ really has at this point. – Nicol Bolas Apr 11 '19 at 05:13
  • 1
    While there are legitimate needs for reflection, perhaps there's a workaround for your use case? Consider elaborating on your reason for asking this. Maybe there's another way to do what you need? – StoryTeller - Unslander Monica Apr 11 '19 at 05:20
  • 1
    This could be done if you can add some types aliases on each class of the hierarchy. Is that an option? – rubenvb Apr 11 '19 at 05:28
  • @StoryTeller my particular case is working, but I hoped to improve the usage. I don't want to provide to work with a base abstract class, though it works. Later, when I get to my PC with a proper internet connection I will update the post with my initial intend. However, I consider the question to be interesting by itself. – Sergey Kolesnik Apr 11 '19 at 05:29
  • @rubenvb what do you mean exactly? – Sergey Kolesnik Apr 11 '19 at 05:30
  • You could do something like `class Inherited : public MakeBaseList` and let MakeBaseList inherit from all the classes and add a typedef for the tuple and their count. – super Apr 11 '19 at 05:53
  • @SergeyKolesnik Each class in the hierarchy can define a type alias `base_tuple` as a tuple of its base classes' `base_tuple` augmented with that class itself. This will need some sort of tuple flattening which is non-trivial although the specific case here might be easier. I didn't say it was going to be trivial :). Let me see if I can conjure up a simplistic implementation. – rubenvb Apr 11 '19 at 07:52
  • @rubenvb this would be way to complicated. Now the only "inconvenience" is that I have to provide an additional template argument (which is a template specialization of a base class). – Sergey Kolesnik Apr 11 '19 at 09:54
  • Eventually, which do you want to obtain 1) all the types of the base classes or 2) static assertion for an inheritance from something bad base class? If 2) is, it would be easily done. – Hiroki Apr 11 '19 at 16:23
  • @Hiroki I need to obtain a tuple AND also use them as template arguments to assert inheritance from the base template specialization. Also it is interesting if there is a way to assert inheritance from a base template class, regardless of its specialization. But I do need those parameters. – Sergey Kolesnik Apr 11 '19 at 16:34
  • @Hiroki it achieves nothing. I would just get the same typenames in the tuple that I pass as arguments. The goal is to get typenames by providing only one argument - inheriting class. Here you provide all the inherited bases by yourself, which makes no sense. – Sergey Kolesnik Apr 12 '19 at 07:03
  • Hmm... Could you edit your code in the question and show more explicit usage snippet and the desired results ? – Hiroki Apr 12 '19 at 09:28

1 Answers1

0

You can't get that list like that with current language, however you could just use std::is_base for your actual problem.

From https://en.cppreference.com/w/cpp/types/is_base_of:

#include <iostream>
#include <type_traits>

class A {};

class B : A {};

class C {};

int main() 
{
    std::cout << std::boolalpha;
    std::cout << "a2b: " << std::is_base_of<A, B>::value << '\n';
    std::cout << "b2a: " << std::is_base_of<B, A>::value << '\n';
    std::cout << "c2b: " << std::is_base_of<C, B>::value << '\n';
    std::cout << "same type: " << std::is_base_of<C, C>::value << '\n';
}

output:

a2b: true
b2a: false
c2b: false
same type: true
darune
  • 10,480
  • 2
  • 24
  • 62