Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
May 24, 2018 T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
While tinkering with some code I eventually found that the following didn't do as I expected import std.conv; import std.stdio; void main() { Foo foo = 5; writeln(foo); } struct Foo{ int i; alias i this; @disable T opCast(T)(); this(int j) {i =j;} } If the cast in the example is implict this code compiles and executes. If the cast is explicit it doesn't. Is there a plan to expose something like 'opImplCast()()' so I can @disable it for some types where I absolutely don't want any accidental type conversions? Shouldn't this just be a feature of D? |
May 23, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd Nijboer | On 23 May 2018 at 17:30, Sjoerd Nijboer via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> While tinkering with some code I eventually found that the following didn't do as I expected
>
> import std.conv;
> import std.stdio;
>
> void main()
> {
> Foo foo = 5;
> writeln(foo);
> }
>
> struct Foo{
> int i;
> alias i this;
> @disable T opCast(T)();
> this(int j)
> {i =j;}
> }
>
> If the cast in the example is implict this code compiles and executes.
> If the cast is explicit it doesn't.
> Is there a plan to expose something like 'opImplCast()()' so I can @disable
> it for some types where I absolutely don't want any accidental type
> conversions?
> Shouldn't this just be a feature of D?
I would REALLY love a way to implement an implicit cast that wasn't `alias this` based... for reasons that are NOT to @disable it :P
|
May 24, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Thursday, 24 May 2018 at 00:53:00 UTC, Manu wrote:
> I would REALLY love a way to implement an implicit cast that wasn't `alias this` based... for reasons that are NOT to @disable it :P
Well, explicit casts can be annoying at times when type conversion wouldn't mean loss of precision, but disabling an implicit cast on any type that has such casts right now means wrapping it in a struct and forwarding all calls to that type except for the type. At that moment you have no implicit casts. (Maybe some explicit ones if you forwarded those.)
But this sounds like a lot of boilerplate and a worse debugging experience.
|
May 24, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu |
> I would REALLY love a way to implement an implicit cast that wasn't `alias this` based... for reasons that are NOT to @disable it :P
Well, explicit casts can be annoying at times when type conversion wouldn't mean loss of precision, but disabling an implicit cast on any type that has such casts right now means wrapping it in a struct and forwarding all calls to that type except for the type. At that moment you have no implicit casts. (Maybe some explicit ones if you forwarded those.)
But this sounds like a lot of boilerplate and a worse debugging experience.
|
May 23, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd Nijboer | On Thursday, May 24, 2018 00:30:03 Sjoerd Nijboer via Digitalmars-d wrote:
> While tinkering with some code I eventually found that the following didn't do as I expected
>
> import std.conv;
> import std.stdio;
>
> void main()
> {
> Foo foo = 5;
> writeln(foo);
> }
>
> struct Foo{
> int i;
> alias i this;
> @disable T opCast(T)();
> this(int j)
> {i =j;}
> }
>
> If the cast in the example is implict this code compiles and
> executes.
> If the cast is explicit it doesn't.
> Is there a plan to expose something like 'opImplCast()()' so I
> can @disable it for some types where I absolutely don't want any
> accidental type conversions?
> Shouldn't this just be a feature of D?
If you don't want an implict cast, then why did you declare an alias this? That's the whole point of alias this. If you want implicit conversions, you use alias this. If you don't, you don't use alias this. I don't understand why it would ever make sense to declare an implicit conversion and then disable it.
Also, if you think that
Foo foo = 5;
is using an implicit cast, you're wrong. That's just calling the constructor. e.g.
struct S
{
this(int i)
{
}
}
void main()
{
S s = 42;
}
compiles, but something like
void foo(S s)
{
}
void main()
{
foo(42);
}
won't.
S s = 42;
is semantically equivalent to
auto s = S(42);
just like it would be in C++.
- Jonathan M Davis
|
May 24, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 24 May 2018 at 01:39:56 UTC, Jonathan M Davis wrote: > If you don't want an implict cast, then why did you declare an alias this? Because I wanted an inconvertible type which was exactly like the int in the example but didn't want the implicit cast. > That's the whole point of alias this. If you want implicit conversions, you use alias this. If you don't, you don't use alias this. I don't understand why it would ever make sense to declare an implicit conversion and then disable it. I think it doesn't make sense to allow us to have any influence on implicit casts. I don't think they should only be existant for primitive types. What if you had a struct with two ints and you coulc convert it with an implicit cast into a different struct with two other ints? For me it makes sense to want an implicit cast there. > Also, if you think that > > Foo foo = 5; > > is using an implicit cast, you're wrong. That's just calling the constructor I know, but 'writeln(foo)' compiles and runs but 'writeln(cast(int) foo)' does not |
May 24, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd Nijboer | On Thursday, 24 May 2018 at 06:42:51 UTC, Sjoerd Nijboer wrote: > On Thursday, 24 May 2018 at 01:39:56 UTC, Jonathan M Davis wrote: >> If you don't want an implict cast, then why did you declare an alias this? > > Because I wanted an inconvertible type which was exactly like the int in the example but didn't want the implicit cast. Doesn’t std.typecons.Typedef do that? https://dlang.org/phobos/std_typecons.html#Typedef |
May 24, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bastiaan Veelo | On Thursday, 24 May 2018 at 07:06:03 UTC, Bastiaan Veelo wrote:
> On Thursday, 24 May 2018 at 06:42:51 UTC, Sjoerd Nijboer wrote:
>> On Thursday, 24 May 2018 at 01:39:56 UTC, Jonathan M Davis wrote:
>>> If you don't want an implict cast, then why did you declare an alias this?
>>
>> Because I wanted an inconvertible type which was exactly like the int in the example but didn't want the implicit cast.
>
> Doesn’t std.typecons.Typedef do that?
> https://dlang.org/phobos/std_typecons.html#Typedef
I didn't know this existed. Cool!
|
May 24, 2018 Re: T opImplCast(T)() so we can add @disable to it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd Nijboer | On Thursday, 24 May 2018 at 07:37:40 UTC, Sjoerd Nijboer wrote:
> On Thursday, 24 May 2018 at 07:06:03 UTC, Bastiaan Veelo wrote:
>> On Thursday, 24 May 2018 at 06:42:51 UTC, Sjoerd Nijboer wrote:
>>> On Thursday, 24 May 2018 at 01:39:56 UTC, Jonathan M Davis wrote:
>>>> If you don't want an implict cast, then why did you declare an alias this?
>>>
>>> Because I wanted an inconvertible type which was exactly like the int in the example but didn't want the implicit cast.
>>
>> Doesn’t std.typecons.Typedef do that?
>> https://dlang.org/phobos/std_typecons.html#Typedef
>
> I didn't know this existed. Cool!
If you need more control, use std.typecons.Proxy to build your own.
|
Copyright © 1999-2021 by the D Language Foundation