opCast cannot implicitly convert a.opCast of type X to Y

Meta jared771 at gmail.com
Wed Feb 14 15:14:24 UTC 2018


On Monday, 12 February 2018 at 02:05:16 UTC, aliak wrote:
> From spec: Cast expression: "cast ( Type ) UnaryExpression" 
> converts UnaryExpresssion to Type.
>
> And https://dlang.org/spec/operatoroverloading.html#cast makes 
> no mention of the return type of opCast. One could think that 
> the return type of opCast would be the return type. But it 
> seems it must be the same as the template parameter of opCast 
> else you get a compile error that seems like it can be much 
> better.
>
> ---
>
> import std.stdio;
>
> struct B(T) {
>     T t;
> }
>
> struct A(T) {
>     T t;
>     auto opCast(U)() {
>         return B!U(cast(U)t);
>     }
> }
>
> void main() {
>     auto a = A!int(3);
>     auto b = cast(float)a; // error
> }
>
> Error: cannot implicitly convert expression a.opCast() of type 
> B!float to float
>
> Is this deliberate?
>
> The use case I have is making an optional type that you can 
> cast to a different type:
>
> auto opCast(U)() const {
>     static if (isOptional!U)
>     {
>         alias V = OptionalTarget!U;
>         return empty ? no!V : some!V(cast(V)front); // it's a 
> range so "front" is the raw value
>     }
>     else
>     {
>             return empty ? no!U : some!U(cast(U)front);
>     }
> }
>
> It would allow for scenarios like:
>
> Optional!int a = 3;
> auto b = cast(float)a;
> // b == some!float
>
>
> Cheers
> - Ali

I think the best way to do this is to implement `map` for your 
optional type.

Optional!U map(U, alias f)()
{
     return empty? no!U : some!U(f(t));
}

Optional!int a = 3;
auto b = a.map!(v => cast(float)v);
assert(is(typeof(b) == Optional!float));


More information about the Digitalmars-d-learn mailing list