Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
February 20, 2016 Why does partial ordering of overloaded functions not take return type into account? | ||||
---|---|---|---|---|
| ||||
module main; struct ThingOne { int thing = 1; } struct ThingTwo { float thing = 2; } struct Test { ThingOne thing() { return ThingOne(); } ThingTwo thing() { return ThingTwo(); } } void main() { Test test; ThingOne thingOne = test.thing(); } test.d(35): Error: main.Test.thing called with argument types () matches both: test.d(17): main.Test.thing() and: test.d(22): main.Test.thing() Why isn't the return type checked when resolving this? Only one of the choices would actually compile so there should be no ambiguity. |
February 20, 2016 Re: Why does partial ordering of overloaded functions not take return type into account? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeremy DeHaan | On Saturday, February 20, 2016 03:24:45 Jeremy DeHaan via Digitalmars-d-learn wrote:
> module main;
>
> struct ThingOne
> {
> int thing = 1;
> }
>
> struct ThingTwo
> {
> float thing = 2;
> }
>
>
> struct Test
> {
> ThingOne thing()
> {
> return ThingOne();
> }
>
> ThingTwo thing()
> {
> return ThingTwo();
> }
>
> }
>
>
> void main()
> {
> Test test;
>
> ThingOne thingOne = test.thing();
> }
>
>
> test.d(35): Error: main.Test.thing called with argument types ()
> matches both:
> test.d(17): main.Test.thing()
> and:
> test.d(22): main.Test.thing()
>
> Why isn't the return type checked when resolving this? Only one of the choices would actually compile so there should be no ambiguity.
I'm unaware of any language that takes the return type into account when overloading. The type the expression test.thing() has to be determined before the assignment is evaluated, and it would be very confusing if the return type were used for overload evaluation in a context like this, because there are other contexts where it would be impossible to do that even theoretically - the simplest being
auto thingOne = test.thing();
So, suddenly, which function gets called would depend on where the expression was used, which would just be confusing and error-prone.
- Jonathan M Davis
|
February 20, 2016 Re: Why does partial ordering of overloaded functions not take return type into account? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 20 February 2016 at 12:29:21 UTC, Jonathan M Davis wrote:
> On Saturday, February 20, 2016 03:24:45 Jeremy DeHaan via Digitalmars-d-learn wrote:
>>
>> snip
>
> I'm unaware of any language that takes the return type into account when overloading. The type the expression test.thing() has to be determined before the assignment is evaluated, and it would be very confusing if the return type were used for overload evaluation in a context like this, because there are other contexts where it would be impossible to do that even theoretically - the simplest being
>
> auto thingOne = test.thing();
>
> So, suddenly, which function gets called would depend on where the expression was used, which would just be confusing and error-prone.
>
> - Jonathan M Davis
With the case of auto of course there is ambiguity, you don't know which one to pick. In my example there should have been no ambiguity at all as only one of the overloads would actually compile. That is what confuses me and why I think return type should be taken into account.
If there are multiple overloads that have the same number of parameters, a very simple addition to the rules of function overloading would be "does it compile?" If only one overload compiles, use it. If more than one compile, there is ambiguity and its an error.
|
February 20, 2016 Re: Why does partial ordering of overloaded functions not take return type into account? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeremy DeHaan | On Sat, 20 Feb 2016 15:47:27 +0000, Jeremy DeHaan wrote:
> If there are multiple overloads that have the same number of parameters, a very simple addition to the rules of function overloading would be "does it compile?" If only one overload compiles, use it. If more than one compile, there is ambiguity and its an error.
So you've got a function with three overloads based solely on return type. You use that overload set once in a function, so the compiler has to try to compile that function three times. That works.
Now you use that overload set twice. The compiler has to compile the function nine times.
You use it ten times. Now the compiler needs to make 59,049 passes for that one function.
|
February 20, 2016 Re: Why does partial ordering of overloaded functions not take return type into account? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeremy DeHaan | On Saturday, 20 February 2016 at 15:47:27 UTC, Jeremy DeHaan wrote: > With the case of auto of course there is ambiguity, you don't know which one to pick. In my example there should have been no ambiguity at all as only one of the overloads would actually compile. That is what confuses me and why I think return type should be taken into account. auto is not the only potential ambiguity. Consider: getValue(); It's not unusual to discard the return value when calling a function. Though a getter isn't a good example of this, of course. Another. How would you reliably do compile-time reflection if this were allowed? If you need to use it in a template to declare a variable of the type returned by foofunc, but there are two different return types for foofunc, then what do you do? > > If there are multiple overloads that have the same number of parameters, a very simple addition to the rules of function overloading would be "does it compile?" If only one overload compiles, use it. If more than one compile, there is ambiguity and its an error. This would create special cases, where a function call succeeds based on context. That seems to me to be something that would a) break expectations and b) be a tremendous inconsistency. |
February 20, 2016 Re: Why does partial ordering of overloaded functions not take return type into account? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Saturday, 20 February 2016 at 17:20:16 UTC, Mike Parker wrote:
> getValue();
>
> It's not unusual to discard the return value when calling a function. Though a getter isn't a good example of this, of course.
Oops. I somehow had it in my head that your example function was getValue(), rather than thing(). Anyway, my point was that the return value is not always used when calling a function with side effects.
|
February 20, 2016 Re: Why does partial ordering of overloaded functions not take return type into account? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Saturday, 20 February 2016 at 17:22:49 UTC, Mike Parker wrote:
> On Saturday, 20 February 2016 at 17:20:16 UTC, Mike Parker wrote:
>
>> getValue();
>>
>> It's not unusual to discard the return value when calling a function. Though a getter isn't a good example of this, of course.
>
> Oops. I somehow had it in my head that your example function was getValue(), rather than thing(). Anyway, my point was that the return value is not always used when calling a function with side effects.
There's also the nice case:
void foo(string s) {
...
}
void foo(int i) {
...
}
string bar() {
...
}
int bar() {
...
}
void main() {
foo(bar); // Which one is it supposed to be?
}
|
Copyright © 1999-2021 by the D Language Foundation