Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!uunet!microsoft!bobatk From: bobatk@microsoft.UUCP (Bob ATKINSON) Newsgroups: comp.lang.c++ Subject: Re: Assignments to reference variables [ and operator.() ] Message-ID: <57649@microsoft.UUCP> Date: 23 Sep 90 21:32:45 GMT References: <8445@jarthur.Claremont.EDU> <57570@microsoft.UUCP> <1677@lupine.NCD.COM> Reply-To: bobatk@microsoft.UUCP (Bob ATKINSON) Organization: Microsoft Corp., Redmond WA Lines: 105 In article <1677@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes: >In article <57570@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes: >> >>-- Please join me in lobbying the ANSI C++ committee to correct this oversight >>in the language definition. Overloading operator.() makes equal sense for >>reference classes as overloading operator->() for pointer classes... >OK. Back to basics. What is `->'? >Well, it is (syntactic sugar) shorthand notation for `*.' (i.e. >dereference and select). So whenever I write: This is true in C. Similar arguments apply in C to += -= <<= *= &=, etc. C++ is not C. See below. > a->b > >(in C anyway) that's always equivalent to: > > (*a).b > >The meaning is clear and unambiguous. Apply the prefix unary dereference >operator to the thing on the left, and then select out a member from the >result. > >Now I've got no problem with (or objection to) allowing overloading for >the unary prefix dereference operator BECAUSE THAT *IS* AN OPERATOR IN >EVERY SENSE OF THE WORD. > >I do object (most violently) however to any attempts to call the selector >`.' a `binary operator' (or to treat it as though it were one). Obviously, >it isn't. > >For all of the binary operators that *I* know of, either the left or the >right operands may be arbitrarily complex *expressions* (so long as these >expressions evaluate to some type of value which is appropriate for the >given category of operator). > >This is clearly *not* true in the case of the selector `.'. For the >selector, the thing on the right *must* be a (qualified or unqualified) >identifier which designates a some member belonging to the type of the >thing on the left. The thing on the right *cannot* be an arbitrarily >complex expression. It must be an identifier. Furthermore, the identifier >*cannot* refer to any complete *object*. Rather, it must refer to a >*member*. These last two sentences would ban pointers to members, which clearly exist today and are useful. >So the selector is *not* an operator. Period. Allowing overloading for >it would make about as much sense as allowing overloading for `{' or `}' >or `::' or `"'. Actually, the thing on the right hand side of a dot operator is precisely a "reference to member." References to members don't actually exist in C++ as defined, but they would bear the same relationship to "pointers to members" (which do exist) as a "reference to a non-member" bears to a "pointer to a non-member." I can elaborate in more detail if you or others would find that helpful. >Likewise, since `->' is just a shorthand notation for a combination of >an operator (i.e. unary prefix dereference) and the selector, allowing >overloading for `->' make as little sense as allowing it for the selector >all by itself, i.e. none whatsoever. Here is my understanding: Overloading of -> was put in to enable the creation of "smart pointers:" objects that clients use like pointers but in which the implementation programmer has control over the dereferencing operation. Such pointers have been found to be valuable in a number of contexts, which I will not explore here. Syntactically, there are two ways that a (normal) pointer can be dereferenced: with '*' and '->'. Writing smart pointers therefore requires that we be able to hook the dereferincing operation of both of these. I see only two ways of doing that: 1) declare that the use of -> is exactly the same as the use of (*). To hook dereferencing, a programmer need only implement the * operation, since this will be used by -> 2) give the programmer ways of hooking * and -> separately. (Both * and -> must be hookable; either you hook them in the same place, or you don't.) C++ has chosen 2). This is the more general of the two, since clearly you can do the same thing in each place. Moreover, 1) flies in the face of the C++ decision to separate the meaning of += from + and =, along with -=, *=, <<=, etc. I believe this was a sound decision, particuarly given the lack of ability to define new operators. >I can't understand why Bjarne and Jim and others have so much difficulty >seeing the fundamental irrationality of allowing operator overloading >to be done to things which are clearly not operators. I guess there is disagreement as to what is "clearly" an operator. >If they really think that this is such a swell idea, then I challenge them >to tell me (and everyone) why they are not suggesting allowing `operator{' >to be overloaded. The root of the difference I claim is that all operators (as so defined) are part of the expression language of C++, where { is solely related to the statement constructs. A more elaborate explanation would require an examination of the detailed syntactic structure of the language. >// Ron Guilmette - C++ Entomologist Bob Atkinson Microsoft