www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - T opImplCast(T)() so we can add disable to it?

reply Sjoerd Nijboer <sjoerdnijboer gmail.com> writes:
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
next sibling parent reply Manu <turkeyman gmail.com> writes:
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 23 2018
next sibling parent Sjoerd Nijboer <sjoerdnijboer gmail.com> writes:
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 23 2018
prev sibling parent Sjoerd Nijboer <sjoerdnijboer gmail.com> writes:
 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
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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 23 2018
parent reply Sjoerd Nijboer <sjoerdnijboer gmail.com> writes:
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 23 2018
parent reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
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
parent reply Sjoerd Nijboer <sjoerdnijboer gmail.com> writes:
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
parent John Colvin <john.loughran.colvin gmail.com> writes:
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.
May 24 2018