How to avoid inout type constructor with Optional type wrapper undoing string type

Timoses timosesu at gmail.com
Tue Jul 24 09:47:00 UTC 2018


On Monday, 23 July 2018 at 18:39:59 UTC, aliak wrote:
> Hi,
>
> I'm playing around with an Optional wrapper type. It stores a 
> type T and a bool that defines whether a value is defined or 
> not:
>
> struct Optional(T) {
>   T value;
>   bool defined = false;
>   this(U : T)(auto ref inout(U) value) inout {
>     this.value = value;
>     this.defined = true;
>   }
> }
>
> To facilitate it's use I have two type constructors:
>
> inout(Optional!T) some(T)(auto ref inout(T) value) {
>     return inout(Optional!T)(value);
> }
>
> Optional!T no(T)() {
>     return Optional!T();
> }
>
> The above produces a problem when working with strings. 
> Basically the type information gets slightly altered so you 
> can't do this:
>
> auto a = [no!string, some("hello")];
>
> You get a type mismatch:
>
> * no!string = Optional!string
> * some("hello") = immutable(Optional!(char[]))
>
> I've created a short code gist, so basically I'm wondering how 
> to get it to compile without changing what's in main()
>
> https://run.dlang.io/is/BreNdZ
>
> I guess I can specialize on string type T, but this is a more 
> general problem that can be shown with:
>
> struct S {}
> alias Thing = immutable S;
> Thing thing = S();
>
> auto x = some(thing);
> auto y = no!Thing;
> auto arr = [x, y]; // no can do buddy
>
> Cheers,
> - Ali


I'm not being very helpful here, just throwing in more questions 
again:

Why does this fail while it works when replacing T with U in 
struct W(T)?? It's so odd. Both T and U seem to resolve to 
"string".

     struct W(T) {
         const T value;
         // Replacing `T value` with `U value` compiles
         this(U : T)(auto ref const T value) {
             pragma(msg, T); // string
             pragma(msg, U); // string
             this.value = value;
         }
     }

     auto defined(T)(auto ref const T value) {
         return W!T(value);
     }

     void main() {
         auto a = defined("hello");
     }

Is this a bug?


More information about the Digitalmars-d-learn mailing list