Date: Tue, 13 Jun 2023 10:46:08 -0400
On Tue, Jun 13, 2023 at 7:10 AM Adrian Hall via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> Hello all.
>
> Proposal:
> Allow casting of Class::*member.submember to Class::*member.
>
> Toy example:
>
Rewritten to use names that are clearly members or types:
struct A { int x_, y_, z_; };
struct B { A a_; };
struct C { B b_; };
B C::*pb = &C::b_; // OK
int C::*px = &C::b_::a_::x_; // Proposed
int C::*py = &C::b_.a_.y_; // Maybe better syntax?
int C::*pz = (&C::b_).a_.z_; // Maybe even better syntax?
It's easy to see that the biggest problem here is with the syntax. Normally
when we have ID::, we know that ID is something with members — a namespace
or a class type (or in C++11-and-later a strong enum type). You're
proposing that we should also allow a (member) variable name in that
position. This is `px` above.
Alternatively, we could say that it should be OK to apply the dot operator
to an expression of pointer-to-member type, to yield another
pointer-to-member. This is `pz` above.
`pz` is probably the best option, syntax-wise, because it naturally permits
us to do things like
B C::*pb = &C::b_;
int A::*px = &A::x_;
int C::*result = pb.a_.*px; // member pointer to some C's `b_.a_.x_`
subobject
The big implementation problem you're going to have to deal with is virtual
bases. Today, it is invalid (a hard compiler error) to write this:
struct A { int x_, y_, z_; };
struct V : virtual A { };
int V::*px = &V::x_;
You'll have to come up with Standard wording that correctly rules out any
new problems along those lines.
Would it be hard to do?
> As far as I am aware there is nothing in the rules of C++
> compilation that would disallow this, since the offset of the submember
> Transform.position.x is known within Potato.
This is true *except* for virtual bases (and subobjects thereof).
Finally, you should think about the two other kinds of subobjects:
struct W { };
struct X : W { W w_; W a_[2]; };
W X::*member_subobject = &X::w_;
W X::*array_element_subobject = &X::a_[1]; // Seems like we can just
support `operator[]` here exactly the same as `.`; is that right?
W X::*base_subobject = &X::???; // Seems like we still lack syntax for
this; is that right?
Or is the `base_subobject` case a bad idea because normally the result of
dereferencing a member pointer is a complete object (in the sense of its
static type is the same as its dynamic type)? Is that true? This deserves
investigation.
struct A { };
struct B : A { };
struct C { B b_; };
B C::*mb = &C::b_;
A C::*ma = mb; // Why is this disallowed? Should it be?
I think this is a good idea, but there's a lot of work to be done first,
that all needs to go into the paper.
Cheers,
Arthur
std-proposals_at_[hidden]> wrote:
> Hello all.
>
> Proposal:
> Allow casting of Class::*member.submember to Class::*member.
>
> Toy example:
>
Rewritten to use names that are clearly members or types:
struct A { int x_, y_, z_; };
struct B { A a_; };
struct C { B b_; };
B C::*pb = &C::b_; // OK
int C::*px = &C::b_::a_::x_; // Proposed
int C::*py = &C::b_.a_.y_; // Maybe better syntax?
int C::*pz = (&C::b_).a_.z_; // Maybe even better syntax?
It's easy to see that the biggest problem here is with the syntax. Normally
when we have ID::, we know that ID is something with members — a namespace
or a class type (or in C++11-and-later a strong enum type). You're
proposing that we should also allow a (member) variable name in that
position. This is `px` above.
Alternatively, we could say that it should be OK to apply the dot operator
to an expression of pointer-to-member type, to yield another
pointer-to-member. This is `pz` above.
`pz` is probably the best option, syntax-wise, because it naturally permits
us to do things like
B C::*pb = &C::b_;
int A::*px = &A::x_;
int C::*result = pb.a_.*px; // member pointer to some C's `b_.a_.x_`
subobject
The big implementation problem you're going to have to deal with is virtual
bases. Today, it is invalid (a hard compiler error) to write this:
struct A { int x_, y_, z_; };
struct V : virtual A { };
int V::*px = &V::x_;
You'll have to come up with Standard wording that correctly rules out any
new problems along those lines.
Would it be hard to do?
> As far as I am aware there is nothing in the rules of C++
> compilation that would disallow this, since the offset of the submember
> Transform.position.x is known within Potato.
This is true *except* for virtual bases (and subobjects thereof).
Finally, you should think about the two other kinds of subobjects:
struct W { };
struct X : W { W w_; W a_[2]; };
W X::*member_subobject = &X::w_;
W X::*array_element_subobject = &X::a_[1]; // Seems like we can just
support `operator[]` here exactly the same as `.`; is that right?
W X::*base_subobject = &X::???; // Seems like we still lack syntax for
this; is that right?
Or is the `base_subobject` case a bad idea because normally the result of
dereferencing a member pointer is a complete object (in the sense of its
static type is the same as its dynamic type)? Is that true? This deserves
investigation.
struct A { };
struct B : A { };
struct C { B b_; };
B C::*mb = &C::b_;
A C::*ma = mb; // Why is this disallowed? Should it be?
I think this is a good idea, but there's a lot of work to be done first,
that all needs to go into the paper.
Cheers,
Arthur
Received on 2023-06-13 14:46:21