D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3968 - Some way to do certain implicit casts with operator overloading
Summary: Some way to do certain implicit casts with operator overloading
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-15 10:29 UTC by bearophile_hugs
Modified: 2018-02-01 07:05 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-03-15 10:29:34 UTC
Here an implicit cast to uint or int can be handy, to avoid the cast (to be able to create a generic "fake int" struct, so for example it can be possible to create a multiprecision integer that acts like a built-in integer), is this possible?


struct Foo {
    int x;
    int opCast(T:int)() {
        return this.x;
    }
}
void main() {
    Foo f = Foo(5);
    auto a1 = new int[cast(int)f]; // OK
    auto a2 = new int[f];          // ERR
}


An implicit cast can be useful in other situations (but I don't know about its possible bad side effects):


struct Foo {
    int x;
    int opCast(T:int)() {
        return this.x;
    }
}
void bar(int i) {}
void main() {
    Foo f = Foo(5);
    bar(f); // Error
}


Steven Schveighoffer has suggested some possible solutions, like:


struct Foo {
   int x;
   uint opCast(T:uint)() { return this.x; }
   int opCast(T:int)() { return this.x; }
   alias opCast this;
}
void main() {
    Foo f = Foo(5);
    int[] a = new int[f]; // line 9
}


Or:

struct Foo {
    uint x;
    uint castToUint() { return x; }
    alias castToUint this;
}


But they don't work. He says at least something like this should:

alias opCast!uint this;

I think that an implicit cast can also lead to bugs, so this has to be designed with care.
Comment 1 Simen Kjaeraas 2018-02-01 07:05:28 UTC
This works today:

struct Foo {
    int x;
    int opCast(T:int)() {
        return this.x;
    }
    alias fn = opCast!size_t;
    alias fn this;
}
unittest {
    Foo f = Foo(5);
    auto a1 = new int[cast(int)f]; // OK
    auto a2 = new int[f];          // Also OK
}

The syntax 'alias opCast!size_t this;' fails to compile, citing 'no identifier for declarator opCast!size_t'.