implicit construction operator

Nick Treleaven nick at geany.org
Fri Mar 2 11:27:48 UTC 2018


On Monday, 26 February 2018 at 21:07:52 UTC, Meta wrote:
> This is possible in the language today using the implicit class 
> construction feature of runtime variadic arrays:
>
> class VArray
> {
>     Variant[] va;
>
>     this(T...)(T ts) { foreach(t; ts) { va ~= Variant(t); } }
> }
>
> void test(VArray ta...)
...
>     test(1, "asdf", false);

Problems:
* The author of `test` has to specifically design support for 
this to work. `test` might be in a library outside the control of 
the programmer.
* `test` might be part of a template such as a type constructor 
taking a type as a template parameter - you can't pass e.g. 
VArray as the type because `test` wouldn't have the ... ellipsis 
- if it did then `test` would be variadic when the type was an 
array (which would be inconsistent).
* If there's an overload `test(int,string,bool)` then implicit 
construction will no longer work - this is a general problem with 
the (Aggregate arg...) feature.

> That said, there is exactly 1 case where I really, really want 
> some kind of implicit conversion:
>
> struct Success {}
> struct Error { string msg; }
>
> alias Result = Algebraic!(Success, Error);
>
> Result connectToHost(IPAddress host)
> {
>     //do some stuff
>     if (operationSucceeded)
>     {
>         return Success();
>     }
>     else
>     {
>         return Error(statusMessage);
>     }
> }
>
> This currently doesn't work, and you instead have to return 
> Result(Success()) and
> Result(Error(statusMessage)).

This is a great example. If we had `@implicit this(T v)` it could 
be restricted to accepting literals, struct constructor call 
expressions and new expressions for `v`. That would allow support 
for your example, plus allow:

void f(Result);
f(Success());
f(Error(statusMessage));

This should only work for an exactly matching implicit 
constructor. Suppose we have a type Q that has an implicit 
constructor for type P, and P has an implicit constructor for int:

void g(Q);
g(P()); // OK
g(5); // error, int is not implicitly convertible to Q

For g(5), the compiler doesn't consider P's `@implicit 
this(int)`, it only matches an implicit constructor of Q when the 
argument type is P exactly.


More information about the Digitalmars-d mailing list