Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string]

Simen Kjærås simen.kjaras at gmail.com
Thu Mar 15 21:03:58 UTC 2018


On Thursday, 15 March 2018 at 15:41:54 UTC, Robert-D wrote:
> Why something like this doesn't compile (with or without the 
> cast on bb.dup)?
>
> struct S {
>     string[string] aa;
>
>     S dup() inout pure {
>         return S(cast(string[string]) aa.dup);
>     }
> }
>
> struct SS {
>     S[] bb;
>
>     SS dup() inout pure {
>         return SS(cast(S[]) bb.dup);
>     }
> }
>
> Or:
>
> const(S)[] ss = [S(["": ""])];
> S[] d = ss.dup;

For this to work, the standard .dup function would need to call 
.dup on each element of the array. Since this may or may not be 
what the programmer wants, the standard library doesn't do it for 
you. Generally, this is called deep-duping, or deep cloning. We 
can implement our own deepdup function:

struct S {
     string[string] aa;

     S dup() const {
         return S(aa.deepDup);
     }
}

struct SS {
     S[] bb;

     SS dup() const {
         return SS(cast(S[])bb.deepDup);
     }
}

import std.traits : Unqual, isArray, isAssociativeArray;

auto deepDup(T)(T obj)
if (!isArray!T && !isAssociativeArray!T)
{
     static if (is(typeof(obj.deepDup))) {
         return obj.deepDup;
     } else static if (is(typeof(obj.dup))) {
         return obj.dup;
     } else static if (is(typeof({ Unqual!T tmp = obj; }))) {
         return obj;
     } else {
         static assert(false, "Can't deepDup a "~T.stringof);
     }
}

auto deepDup(T)(T[] arr) {
     Unqual!T[] result;
     result.reserve(arr.length);

     foreach (e; arr) {
         result ~= e.deepDup;
     }

     return result;
}

auto deepDup(T : V[K], K, V)(T aa) {
     alias UV = Unqual!V;
     alias UK = Unqual!K;
     UV[UK] result;

     foreach (k, v; aa) {
         UK kdup = k.deepDup;
         UV vdup = v.deepDup;

         result[kdup] = vdup;
     }

     return result;
}

--
   Simen


More information about the Digitalmars-d-learn mailing list