Topic: Pointers to members


Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sat, 28 May 1994 17:50:29 GMT
Raw View
Here's the proposal to complete pointers to members and add
a couple of convenience operations.
------------------------------------------------------------

                                  ISO: WG21/N0xxx
                                  ANSI: 93-0xxx
                                  Author: John Max Skaller
                                  Date:  9/1/94
                                  Reply to: maxtal@suphys.physics.su.oz.au


"COMPLETING POINTER TO MEMBER FUNCTIONALITY"
------------------------------------------

Pointers to members exist principally to enable late binding
of the object pointer, as a type-safe alternative
to use of casts and the offsetof macro.

Such a system must be functionally complete to be of more
than limited use. Such a system must be notationally
complete and symmetrical to be of use in templates.

Unfortunately, they aren't. Consider the following:

   struct Inner {
     Mem mem;
   };
   Mem Inner::*ptmem = &Inner::mem;

   struct Outer {
     Inner inner;
   };
   Inner Outer::*ptminner = &Outer::inner;

   Outer outer;
   Outer *pouter = &outer;


PROPOSAL 1: Forming pointers to members
---------------------------------------

If a class type Outer contains an member inner of class type Inner and
Inner contains a member mem of type Mem, then Mem may be considered
as a member of Outer and a pointer to member can be obtained
with the notation:

   Mem Outer::ptoim* = &Outer::inner.mem;

Comment: this operation is required for functional completeness
of pointers to members.


PROPOSAL 2: Adding pointers to member together
----------------------------------------------

If a class type Outer contains a member inner of class type Inner,
and Inner contains a member mem of type Mem, then a pointer
to member ptm of type Mem Inner::* may be added to a pointer
to member ptminner of type Inner Outer::* to obtain a
pointer to member of type Mem Outer::* such that

       ptminner .* ptmem == &Outer::inner.mem;

Comment: this operation is required for functional completeness
of pointers to members.

PROPOSAL 3: Adding a member to a pointer to member
--------------------------------------------------

If a class type Outer contains a member inner of class type Inner,
and Inner contains a member mem of type Mem, then the member mem
may be added to a pointer to member ptminner of type Inner Outer::*
to obtain a pointer to member of type Mem Outer::* such that

       ptminner . mem == &Outer::inner.mem;

Comment: this operation can be defined by

       ptminner . mem == ptminner .* (&Inner::mem)

which utilises the new operation defined in proposal 2,
provided the class of which mem is a member is known
to be Inner.

PROPOSAL 4: Conveniences
------------------------

The following two overloads are added for convenience

    pouter .  inner     ==   &(pouter->inner)
    pouter .* ptminner  ==   &(pouter->*ptminner)


Neither are essential either for functional completeness
or referential completeness, however the use of infix notation
is vastly superior to the clumbsy form of the RHS when
several levels of containment or indirection are involved:

    pa . b . c . d == (&(&(pa->b)->c)->d


------------------------------------------------------------

Comments: ALL the operations involved in this proposal
simply add the RHS offset to the LHS, yielding an
exprsssion of the same category (lvalue, pointer, pointer to member)
as the LHS, but indicating the member contained at the nominated
offset.

I call this an 'incast', the operation is always safe and
corresponds to the notion that a nested (or inner) member, which
is a member of a member, is also in some sense a member of the
outer structure. Incasting consists of adding an offset to
an address with appropriate type changes.

The inverse of this operation, which I call an 'outcast',
is unsafe but extremely useful, it corresponds to the
idea that we can find the address of an object if we know
the address of a contained object and which member of
the containing object it is: the operation is simply
a subtraction with appropriate type changes.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA