Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!mcvax!kth!draken!tut!tukki!sakkinen From: sakkinen@tukki.jyu.fi (Markku Sakkinen) Newsgroups: comp.lang.c++ Subject: Re: Arguments to Overloaded Operators Keywords: overloading, type inference Message-ID: <883@tukki.jyu.fi> Date: 13 Jun 89 08:39:04 GMT References: <11032@orstcs.CS.ORST.EDU> <1100@cadillac.CAD.MCC.COM> <238@pink.ACA.MCC.COM> <868@tukki.jyu.fi> <244@pink.ACA.MCC.COM> Reply-To: markku@jytko.jyu.fi (Markku Sakkinen) SAKKINEN@FINJYU.bitnet (alternative) Organization: University of Jyvaskyla, Finland Lines: 201 The front end requires me to put here more new than included lines - let's try some extra blank lines. In article <244@pink.ACA.MCC.COM> rfg@pink.aca.mcc.com.UUCP (Ron Guilmette) writes: >In article <868@tukki.jyu.fi> markku@jytko.jyu.fi (Markku Sakkinen) SAKKINEN@FINJYU.bitnet (alternative) writes: >>In article <238@pink.ACA.MCC.COM> rfg@pink.aca.mcc.com.UUCP (Ron Guilmette) writes: >>>In article <1100@cadillac.CAD.MCC.COM> vaughan@mcc.com (Paul Vaughan) writes: >>>>Two questions: >>>>1) >>>>Has anyone considered overloaded functions/operators that are selected >>>>not only by a match of parameter types, but also according to the >>>>return type ... ... >>I think there is a plausible fundamental reason, independent of compiler >>implementation (although omitting this kind of overloading obviously >>makes the compiler writer's job a little easier, too). >> >>In C++ expressions, the context of each subexpression (e.g. a function >>invocation) in general only weakly determines the expected type of >>the subexpression. >So far we are in agreement. As an example of just what you are >talking about, assume that we have: > > typedef ... A; > typedef ... B; > class C { > public: > C () {} > operator A () { ... } // type converter C => A > operator B () { ... } // type converter C => B > }; > > void func (A a); > void func (B b); > C c; > ... > func (c); > >Note that the ambiguous thing here is the *variable* "c". Note also that >there are already rules in the language which state (exactly) what is supposed >to happen in such cases. This example is beside the point: it is about overloading based on _argument_ types, not _return_ type; we had no argument (no pun intended) about that. However, your last statement happens to be incorrect: in a case like this, the C++ compiler (release 1.2) signals "error: ambiguous argument for overloaded func()" Further: - There is nothing ambiguous about the variable c itself: it is of class C, and the ambiguity is only in the invocation of func. - The example would also need an explicit "overload func;" declaration, although Stroustrup currently seems to regret that. >>This is in part caused by the automatic type conversions, >>of which there are too many to my personal liking. >What to obviously meant was "builtin" type conversions. > >I agree with what you said, but to be more precise, you would have to say >that that the ambiguity problems are caused *all* forms of type >conversions (both builtin and user-defined) which may be applied >*implicitly*. That is rather exactly what I originally said, if you read more carefully. >>One example of these >>is the widening of char values to int in many contexts: it even prevents us >>from declaring an overloaded function pair corresponding to the _argument_ >>types char and int. >Who sez? I believe this is legal now. For instance, the aforementioned compiler sez: "warning: the overloading mechanism cannot tell a void (int ) from a void (char )" And subsection 6.6 of the C++ Reference Manual (at the end of Stroutrup's book) says: "First, any operands of type char, unsigned char, or short are converted to int." Knowing is better than believing. >>The automatic type conversions would be most problematic in the following case: >>no overloaded function matches the expected type exactly, but more than >>one of them would qualify for automatic conversion. >This is almost the same as the example I gave above except that in my example, >the "ambiguous subexpression" is a variable and not a function call. > >Again, I have to reiterate, the language already has rules for such cases. >What is there to prevent these rules from being extended to handle the >additional (very similar) case(s) of functions overloaded by return types? As proved above, the language does _not_ have such rules. And how could there be any sensible rule to decide automatically between A and B in the example? >In effect, such functions could simply be treated as if they *all* returned >some "universal" type for which there were a set of implicit conversion >operators declared, one for each possible return type for which an overloading >of the given function exists. Then, further ambiguity resolution could take >place as normal (i.e. as it would for my example above). Now this further >ambiguity resolution might result in the compiler issuing an error (as I >believe it would for my example above) because there is still too much >ambiguity, but at least we could use our "functions-overloaded-by-return-types" >in most contexts. That would be better than the current state of affairs >where we are prevented from even declaring such overloadings. The "universal type" idea does not look logical at all: the problem is to choose the "right" function in the first place, not to invoke _some_ function and then convert its result. >>Of course, there would be even situations where there is no cue at all to >>which overloaded alternative is appropriate, e.g. >> (void) juggle (a, b, c); >In that case, as I say, you should allow the compiler to say "this is >ambiguous" and issue an error to that effect. Here we agree completely. >Of course the example you gave might not be ambiguous if one (and only >one) of the "overloadings-of-juggle-based-on-return-types" had a return >type for which there was a user-defined type conversion operator >which could convert the given return type to a void type. Sorry, my example was not the best possible. Although that is the currently recommended idiom at least in C for stating, "I know the function yields a result but I want to discard it", in C++ it will indeed cause a conversion function to be invoked if the result type of juggle is a _class_ for which an "operator void ()" has been defined! Therefore, to get a situation without any cues we must leave out '(void)'. (I checked both cases.) >>If overloading based on return type were to be introduced, >>then compilers should issue at least warnings at every place where >>the choice is ambiguous. >"Ambiguous" is in the eye of the compiler/language. For cases where the >standard disambiguation rules can be applied (and leave you with only one >possible meaning) there should *not* be any errors or warnings issued. >For cases where the attempt at disambiguation (within the language >guidelines) still leaves you with multiple possible meanings, you >should *always* get an error. I don't think there was any disagreement directly on this point. Nevertheless, especially with regard to what you are saying below, you probably want the disambiguations / implicit conversions to cater for the largest possible portion of cases. I consider that to be dangerous because of new possibilities for undetected programming errors. (Already in my ECOOP'88 paper I argued against the principle of using one-argument constructors automatically as type conversion functions.) This is somewhat analogous to the problems and errors caused by simple-minded linearisation of multiple inheritance (see e.g. various papers of Alan Snyder). >>... I am afraid that one would be obliged to >>use a lot of explicit type casts, and the convenience of the feature >>would thus sometimes be questionable. >Wrong! As for my example above, explicit casts would only be needed >for cases which are *still* ambiguous after application of all available >disambiguation rules. It depends! It would certainly be _possible_ to program so that very few cases remain ambiguous, but it might be difficult. >> However, there certainly are >>cases in which the facility would be very nice to have. >Right! > >-- >// Ron Guilmette - MCC - Experimental Systems Kit Project >// 3500 West Balcones Center Drive, Austin, TX 78759 - (512)338-3740 >// ARPA: rfg@mcc.com >// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg In the meantime, I have already seen a couple of responses from compiler implementers: they anticipated great difficulties for the idea, so we are probably left with "wouldn't it be nice sometimes". Markku Sakkinen Department of Computer Science University of Jyvaskyla (a's with umlauts) Seminaarinkatu 15 SF-40640 Jyvaskyla (umlauts again) Finland