Path: utzoo!attcan!ncrcan!hcr!stan From: stan@hcr.UUCP (Stan Jarzabek) Newsgroups: comp.lang.c++ Subject: RE: the best match for an overloaded function Keywords: overloading Message-ID: <1889@hcr.UUCP> Date: 28 Aug 89 19:46:37 GMT References: <1834@hcr.UUCP>, <9820@alice.UUCP> Reply-To: stan@hcrvx1.UUCP (Stan Jarzabek) Organization: HCR Corporation, Toronto Lines: 126 In response to the question: What does it mean to be "the best match" for an overloaded function? Andrew Koenig (ark@europa.att.com) writes: >In article <1834@hcr.UUCP>, stan@hcr.UUCP (Stan Jarzabek) writes: >> What does it mean to be "the best match" for an overloaded function? >> Here is an example: >> struct X {}; >> struct Z >> { Z(X) {} >> }; >> int f(int,X) {} >> int f(short,Z) {} >> main() >> { >> short s; >> X x; >> f(s,x); >> } >> According to the definition from the manual, there is no best match for >> f(s,x), as the intersection of sets is empty. The 2.0 selects f(int,X), which >> confirms the intuition and contradicts the manual definition. >I think this is a bug in cfront. The best match for `s' is >clearly `short' and the best match for `x' is equally clearly >`X', so there's no reason to choose f(int,X) over f(short,Z). I hope this is not a bug in cfront but an intended behavior. The cfront seems to notice that f(int,X) is a better match for f(s,x) than f(short,Z),as it requires only standard promotion (short->int), while the second requires user-defined conversion (X->Z). The behavior of cfront in other, similar cases make me think that cfront understands "the best match" in that way. If I am right, then the definition of the "best match" from the manual cannot be the one which is implemented in cfront. For me, the above example also shows that the manual definition (i.e. "the best-matching function is the intersection of sets of functions that best match on each argument") is counterintuitive in certain cases. >> In the example below, the compiler behaves inconsistently, and contradicts both >> the intuition and the definition from the manual. >> struct X >> { >> int a; >> X(int i) { a = i; } >> operator int() { return a; } >> }; >> int f(short,short,short) { return 1; } >> int f(char,char,short) { return 2; } >> int f(X,short,short) { return 3; } >> main() >> { >> short s = 1; >> X x(1); >> f(x,s,x); //2.0: f(X,short,short) is called >> f(x,x,s); //2.0: ambiguous call >> } >> The last example shows that the intuitive meaning of "the best match" may not >> be obvious. >Here I think cfront is correct and matches what the manual says. >Let's look first at the first call, f(x,s,x). >The best match for the first `x' argument is surely X. The >best match for `s' is `short', and the best match for `x' >is also `short' -- not the greatest but it's the best available. >Therefore this calls f(X,short,short). >In the second call, f(x,x,s), the best match for the first `x' is >again X. The second argument is an X and the choice is between >short and char. There is no conversion from X to short or char, >just to int. There is no reason to prefer X->int->short or >x->int->char, so the second argument is ambiguous. Hence the >entire call is ambiguous. > --Andrew Koenig > ark@europa.att.com As I understand this, according to the definition from the manual, in both cases function f(X,sort,short) should be called: To find the best match, for both function calls you intersect sets: { f(X,short,short) } , { all functions } , { all functions } The intersection of sets gives you f(X,short,short). You can have two conversions for one argument and this does not necessarily mean that the function call in ambiguous. The statement saying that "if conversions for any one argument are ambiguous, the call is ambiguous" was in the draft manual, but I could not find it in the new language manual. (Fortunately, as cfront never behaved in that way, and if it did, I would again call this counterintuitive.) The new manual specifically says that "where identical conversions exist for an argument, matching is determined by other arguments (if any)". It seems to me that, although not always consistently, cfront tries to implement the ambiguity test according to what the new manual says. To support my interpretation, here are two more examples: Assuming function declarations from the last example, in the function call f(x,i,i) second argument "is ambiguous", but cfront finds f(X,short,short) as the best match; also, in f(1,s,s) first argument "is ambiguous", but cfront finds f(short,short,short) as the best match. I think cfront is right in those particular cases. There are bugs in the cfront's overloading resolution mechanism, for example, it is enough to change the order of function declarations in the last example to obtain different results - definitely, the result of overloading resolution should be function-declaration-independent. But here I am concerned with the underlying principle rather than with small bugs. So, the problem remains: what is the definition of the best match for an overloaded function with many arguments? Stan Jarzabek, HCR Corporation, Toronto e-mail: stan!hcr