Thread overview | ||||||
---|---|---|---|---|---|---|
|
March 10, 2015 What's the rationale here? alias this and function arguments | ||||
---|---|---|---|---|
| ||||
struct S { int a; this(T)(T v) { this = v; } void foo(T)(T v) { import std.conv : to; a = v.to!int; } alias foo this; } void bar(S s){} void main() { S s0; s0 = "3"; //OK S s = "3"; //OK bar("3"); //Not OK } It would seem logical that the last one would work as well. What's the reasoning behind this? |
March 10, 2015 Re: What's the rationale here? alias this and function arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin Attachments: | On Tue, 10 Mar 2015 10:27:13 +0000, John Colvin wrote:
> struct S {
> int a;
> this(T)(T v)
> {
> this = v;
> }
> void foo(T)(T v) {
> import std.conv : to;
> a = v.to!int;
> }
> alias foo this;
> }
>
> void bar(S s){}
>
> void main()
> {
> S s0;
> s0 = "3"; //OK S s = "3"; //OK bar("3"); //Not OK
> }
>
> It would seem logical that the last one would work as well. What's the reasoning behind this?
autoconversion for function arguments can lead to bug-ridden code, and is a perfect way to disaster. besides, it's ambiguous. let's imagine that we have struct `S1`, which can be created from string too, and overload of `bar` as `void bar (S1 s)`. what `bar` compiler should choose for `bar ("3")`?
so compiler doesn't try to guess how to convert your function argument from valid constructor args to structs. this decreases the change to introduce a hard-to-detect bugs with implicit construction, and also increases the readability (imagine surprised reader that sees `bar("3")` in the code, but no `bar` overload that accepts string).
C++ tries to be "smart" here, and fails. D doesn't try to be smart, as it's not a compiler work to guess what you meant.
|
March 10, 2015 Re: What's the rationale here? alias this and function arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Tuesday, 10 March 2015 at 10:27:14 UTC, John Colvin wrote:
> struct S
> {
> int a;
> this(T)(T v)
> {
> this = v;
> }
> void foo(T)(T v)
> {
> import std.conv : to;
> a = v.to!int;
> }
> alias foo this;
> }
>
> void bar(S s){}
>
> void main()
> {
> S s0;
> s0 = "3"; //OK
> S s = "3"; //OK
> bar("3"); //Not OK
> }
>
> It would seem logical that the last one would work as well. What's the reasoning behind this?
Do you think that the parameter should be automatically created from the argument ? Is this kind of thing even possible in another context ?
Your alias looks more like an ```opCall()```. To my eyes the strange thing is that if you add the following statement at the end of you sample:
---
s(0);
---
DMD outputs:
```Error: cannot resolve type for s.foo(T)(T v)```
|
March 10, 2015 Re: What's the rationale here? alias this and function arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Tuesday, 10 March 2015 at 10:36:21 UTC, ketmar wrote:
> On Tue, 10 Mar 2015 10:27:13 +0000, John Colvin wrote:
>
>> struct S {
>> int a;
>> this(T)(T v)
>> {
>> this = v;
>> }
>> void foo(T)(T v) {
>> import std.conv : to;
>> a = v.to!int;
>> }
>> alias foo this;
>> }
>>
>> void bar(S s){}
>>
>> void main()
>> {
>> S s0;
>> s0 = "3"; //OK S s = "3"; //OK bar("3"); //Not OK
>> }
>>
>> It would seem logical that the last one would work as well.
>> What's the reasoning behind this?
>
> autoconversion for function arguments can lead to bug-ridden code, and is
> a perfect way to disaster. besides, it's ambiguous. let's imagine that we
> have struct `S1`, which can be created from string too, and overload of
> `bar` as `void bar (S1 s)`. what `bar` compiler should choose for `bar
> ("3")`?
Ah yep, overloading, that was it. I have the feeling i've asked this before and someone else explained it to me but I had forgotten. Cheers
|
Copyright © 1999-2021 by the D Language Foundation