C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Base class reflection

From: Billy Martin <bmartin_at_[hidden]>
Date: Tue, 31 Jan 2023 12:22:55 -0800
You can't do this because there isn't any code that knows both B and D at
compile time.

The case I'm thinking of involves some templated container that has an
object of type D. (Maybe it's a type erasure system, a smart pointer,
whatever). That container knows the type D because it was passed as a
template argument when it was instantiated with a brand new D object.
Somewhere else, some other code has a pointer B* and they want it to point
to this object, but they don't know what type D is (it might not even be
knowable until runtime). The container, on the other hand, doesn't know
about the type B because it's just a container template and it turns out
C++ has literally no way to query a type for its base classes for some
reason. So there is no point where you can do the safe conversion
static_cast<B*>(D*) because no code knows both types. There is also no way
for the code that is using the container to tell it about B using another
template call because templated virtual functions don't exist in C++ either
(and the container uses type erasure, which allows code that doesn't know
about D to have it in the first place)

If there were a way to get the base classes of a type at compile time, then
this would be simple. The container could make that list at compile time,
and then there could be a virtual function that takes a type-erased pointer
to a base class, and then at runtime the container can go through this list
of base classes and figure out which one it is, and then it will have both
type D and type B and can safely do the conversion.

(When I say type-erased pointer what I mean is some system that looks like:
struct TypeErased<T> : TypeErasedBase {...}; and then someone can give you
a TypeErasedBase* by calling your virtual function, and you can try to do
dynamic_cast<TypeErased<T>*> on it for any type T that you know. But you
have to know the type T exactly at compile time. Trying to dynamic_cast to
TypeErased<B>* where B is a base of T wont work. However if you have a
finite list of types then you can check each one, so if you can somehow
know the class hierarchy then you can search for the right type. Hell, you
might even be able to make the type erasure system somehow mimic the class
hierarchy of arbitrary types, so that dynamic_cast<TypeErased<B>*> would
actually work on a TypeErased<D>, I don't know. I bet if they had added
this feature back in 2009 when it was first proposed then brilliant people
would have done all sorts of miraculous things with it by now)

To summarize:

a) Type Erasure is, like, so hot right now, oh my god.

b) there are issues with using Type Erasure on polymorphic classes.

c) this feature would bridge that gap.

Billy

On Tue, Jan 31, 2023 at 12:03 AM Jonathan Wakely <cxx_at_[hidden]> wrote:

What if it doesn't find B? How does this feature help you?

If you already know B a priori, why can't you just check if D is derived
from B (which is easy today) and check if D* is convertible to B* (also
easy)? Why is your proposed feature needed for this?

Received on 2023-01-31 20:23:09