On Saturday, 30 May 2015 at 15:24:49 UTC, Adam D. Ruppe wrote:
On Saturday, 30 May 2015 at 14:10:35 UTC, IgorStepanov wrote:
static Foo opImplicitConstructFrom(T)(T val) if(is(T : int))
I briefly mentioned this at the dconf and thinking about it a
bit more, I think there's only two cases where we want implicit
construction: function argument lists and function return
values. (The syntax doesn't really matter, but I'd do it
similar to C++ and just slap an @implicit on a regular
constructor).
So:
struct Foo { @implicit this(typeof(null)) {} }
Foo test() {
return null;
}
Right now, that return null would say "cannot implicitly
convert null to Foo". But since it is on a return statement and
we have an implicit constructor, it would automatically rewrite
that to return Foo(null); and be happy with it.
Note that this does NOT change
Foo foo = null;
because that already works with a standard constructor today!
Similarly, foo = null is handled with opAssign. So no change
needed there.
Anyway, the trickier case is function calls:
void test(Foo) {}
test(null); // should do test(Foo(null));
How does that interact with operator overloading? (I'd note
that C++ does this so we could always borrow their rules too.)
My proposal would be that if something matches exactly without
implicit conversion, use that. Otherwise, try the implicit
construction and issue an error if more than one match.
This would work the same as arrays today:
void a(int[]) {}
void a(long[]) {}
void a(typeof(null)) {}
void main() { a(null); }
That compiles. Comment the third line though and get:
b.d(5): Error: b.a called with argument types (typeof(null))
matches both:
b.d(1): b.a(int[] _param_0)
and:
b.d(2): b.a(long[] _param_0)
So I think that's doable and shouldn't break any existing code
as it is a new opt-in keyword. Just will have to watch for
regression bugs...
But that'd take care of the null problem with library AAs....
and I could use it to make my var type all the more wild :P
This would also greatly improve Variant and Algebraic