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));