Thread overview
T opImplCast(T)() so we can add @disable to it?
May 24, 2018
Sjoerd Nijboer
May 24, 2018
Manu
May 24, 2018
Sjoerd Nijboer
May 24, 2018
Sjoerd Nijboer
May 24, 2018
Jonathan M Davis
May 24, 2018
Sjoerd Nijboer
May 24, 2018
Bastiaan Veelo
May 24, 2018
Sjoerd Nijboer
May 24, 2018
John Colvin
May 24, 2018
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
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
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
> 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
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
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
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
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
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.