C++ Logo


Advanced search

Re: Update: P1240R2 — Scalable Reflection - Clarifications

From: Daveed Vandevoorde <daveed_at_[hidden]>
Date: Mon, 31 Jan 2022 12:41:06 -0500
> On Jan 31, 2022, at 12:08 PM, Peter Dimov <pdimov_at_[hidden]> wrote:
> Daveed Vandevoorde wrote:
>>> This reminds me of an observation I had: it would have been nice if we
>>> could actually form pointer to member to a specific base class, so
>>> that we can then reflect it.
>> I can see how that could be useful: Extend the notion of pointer-to-member to
>> also be able to designate bases.
>> (That’s orthogonal to reflection though.)
>>> Because as-is, if you have two bases of the same type, there's no way
>>> you can differentiate between them just by their type.
>> Even “not as is”: It’s an ambiguous question to ask?
> It's not ambiguous if you have reflection information.

Right. (I see that as not “just by their type”.)

> In Boost.Describe, I support a "modifier" mod_inherited, which includes the
> inherited members in the "members_of" list. I don't currently support it for
> the base classes, but I could. So when you have
> struct B {};
> struct D1: B {};
> struct D2: B {};
> struct C: D1, D2 {};
> and you say describe_bases<C, mod_any_access | mod_inherited>, you would
> get a list of base class descriptors [desc(D1), desc(B), desc(D2), desc(B)].

Okay, so like the alternative API I described where you also get indirect bases.
Do the descriptors maintain information about the derivation path?

> So you
> have two descriptors about a base class of type B, but they refer to different
> bases. And if the base class descriptor contained a member pointer to the base,
> like data member descriptors contain a member pointer to the data member,
> you would be able to go from C* to the first B* using the first pointer, and to
> the second B* using the second pointer.
> Not sure if this makes any sense. :-) I hope it does.

I think so.

That info is present in P1240 reflection, but currently you’d have to maintain side structures yourself since there is no reflected notion of “indirect base” or “derivation path” or anything like that. (See also the apply_to_all_data_members example in P1240.)

IIRC, in the context of P1240 someone once suggested that we should be able to write something like:

 D *p;
 auto *pb = p->[:bases_of(^D)[0]:];

(assuming D has a base class). That’s similar to your suggestion of a more general pointer-to-member value concept, but it has the advantage of generalizing to bit fields as well.

It definitely seems worthwhile to me. We could probably integrate _that_ in the P1240 work since we’re going to have to give some semantics to p->[:…:] in any case.


Received on 2022-01-31 17:41:09