Topic: Why not overload member access operator "." ?


Author: jimad@microsoft.com (Jim Adcock)
Date: Mon, 24 Jan 1994 19:40:46 GMT
Raw View
In article <2hbi29$6nn@wega.rz.uni-ulm.de> kohlhaas@faw.uni-ulm.de (Bernhard Kohlhaas) writes:
|Hi,
|this is my first posting to this group so if this is the wrong place to ask
|or if this has been discussed before please provide a pointer to the correct location.

Well, for a first posting, you certainly have a knack.  I first proposed to the
committee that this unnecessary restriction and needless nonorthogonality
be removed back in 1989.  After sitting on the proposal for several
years, committee members decided not to pursue this proposal, or so
I have been told informally.  One committee member wrote an
"analysis" against the proposal.  One committee member wrote a
rebuttal "for" the proposal.  In the end [by my indirect understanding]
there aren't enough committee members who 1) understand references
2) understand how operator-> works 3) understand the operator.()
proposal and 4) think its worth adding to get the proposal into
the standard.  Note that one person has already implemented the
proposal as an extension to the g++ compiler.

This proposal has already been flamed back and forth on this forum
and others many times, with much heat and little understanding.
Fundamentally what goes into the standard is what committee members
can agree on, not what is necessarily best or good.  If committee
members cannot agree on a feature, then it only remains to individual
compiler vendors to implement a feature as an extension -- if the
individual compiler vendors believe that is something good to do.





Author: kohlhaas@faw.uni-ulm.de (Bernhard Kohlhaas)
Date: 16 Jan 1994 14:13:29 GMT
Raw View
Hi,
this is my first posting to this group so if this is the wrong place to ask
or if this has been discussed before please provide a pointer to the correct location.

The ARM, p 330, states that the operator "." can not be overloaded, so the
following code is impossible:

class myReference<T> {
 ...
 public:
  T& operator.();
 ...
};

The nice feature of this would be that similar to overloading the operator->()
for "smart-pointers" one could implement some kind of "smart reference".

The meaning of the interpretation of the overloaded operator.() should be similar
to operator->() so "x.m" would be resolved to "(x.operator.()).m" .

The reason the ARM gives for not allowing to overload operator.() is that
is has a predefined meaning for any class.
Thus in the example given above it seems that I could never access a member function of
myReference<T>. But this could still be possible when using the scope resolution
operator, e.g.:

 myReference<T> x;

 x.m;   // access member function of object of class T returned by operator.();
 x::.m; // invokes global "." operator, thus accessing member function of
        // myReference<T>.

Well, I'm not a C++ expert and I know that this idea still leaves a lot
of unanswerd questions, e.g. what happens
if I use the "->" operator on a "myReference<T>*" or what happens within
the defined member functions of "myReference<T>" when accessing members ?

So if this idea has been discussed before, please direct me to the right place.
If this is a new subject however, I'd like some comments on this idea by
some C++ experts.

Thanks,


Bernhard Kohlhaas


--
Bernhard Kohlhaas
-------------------------------------
| Internet: kohlhaas@faw.uni-ulm.de |
|   Bitnet: kohlhaas@dulfaw1a       |
-------------------------------------
#include <StandardDisclaimer>




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Mon, 17 Jan 1994 14:14:10 GMT
Raw View
kohlhaas@faw.uni-ulm.de (Bernhard Kohlhaas) writes:

>Hi,
>this is my first posting to this group so if this is the wrong place to ask
>or if this has been discussed before please provide a pointer to the correct location.

This is the right place to ask.
Yes, it has been discussed before (understatement!).
Unfortunately I didn't save the threads.
Nor do I have a copy of the proposal written by Jim Adcock
and submitted to the C++ committee.

That proposal was unfortunately rejected by the committee,
for reasons which have been discussed by Andrew Koenig in
a recent article on one of the "bool" threads.
(I won't try to paraphrase him here.)

>The ARM, p 330, states that the operator "." can not be overloaded, so the
>following code is impossible:
>
>class myReference<T> {
> ...
> public:
>  T& operator.();
> ...
>};

Yes, this gratuitous non-orthogonality is indeed disappointing.

>The nice feature of this would be that similar to overloading the operator->()
>for "smart-pointers" one could implement some kind of "smart reference".
>
>The meaning of the interpretation of the overloaded operator.() should be
>similar to operator->() so "x.m" would be resolved to "(x.operator.()).m" .

Yup.  That was exactly what Jim Adcock proposed.
I've even implemented it for GNU C++ (patch available on request).

>The reason the ARM gives for not allowing to overload operator.() is that
>is has a predefined meaning for any class.

Never mind that this doesn't stop you from overloading operator&() or
operator=().

>Thus in the example given above it seems that I could never access a
>member function of myReference<T>. But this could still be possible
>when using the scope resolution operator, e.g.:
>
> myReference<T> x;
>
> x.m;   // access member function of object of class T returned
>        // by operator.();
> x::.m; // invokes global "." operator, thus accessing member function of
>        // myReference<T>.

An excellent suggestion!

As I recall, the inability to refer to the members of a class which
overloaded operator.() was one of the major complaints put by those
who argued against the proposal.  You suggestion is very intuitive
and extremely easy to implement, and completely solves this problem.

>Well, I'm not a C++ expert and I know that this idea still leaves a lot
>of unanswerd questions, e.g. what happens
>if I use the "->" operator on a "myReference<T>*" or what happens within
>the defined member functions of "myReference<T>" when accessing members ?

If you use the "->" operator on a myReference<T>*, you get the predefined
operator->(), which does not invoke the overloaded operator.().
Similarly the implicit "this->" inside member functions does not
invoke the overloaded operator.().
This is the same as with all other overloaded operators: operator.() is
invoked only when there is a "." explicitly present in the source code.

--
Fergus Henderson        |   "People who brook no compromise in programming
                        |   languages should program in lambda calculus or
fjh@munta.cs.mu.OZ.AU   |   machine language, depending." --Andrew Koenig.