Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
March 15, 2018 Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] | ||||
---|---|---|---|---|
| ||||
struct S { string[string] aa; S dup() inout pure { return S(aa); } } void main() { auto s = S(["": ""]); s.dup(); } Result: Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] I need help with the above program. |
March 15, 2018 Re: Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert-D | On Thursday, 15 March 2018 at 11:18:48 UTC, Robert-D wrote: > struct S { > string[string] aa; > > S dup() inout pure { > return S(aa); > } > } > > void main() { > auto s = S(["": ""]); > s.dup(); > } > > Result: > Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] > > > I need help with the above program. This is where things go wrong: > S dup() inout pure { 'inout' means that this function can keep the const, immutable or mutable status of the type on which the function is called. This means that an inout function has to treat the object as const, because otherwise the function would break the guarantees of immutable and const. When using inout on a function, you always want to put inout on something else too - either a ref parameter or the return value. In your case, this works: inout(S) dup() inout pure { return inout(S)(aa); } -- Simen |
March 15, 2018 Re: Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Thursday, 15 March 2018 at 11:33:49 UTC, Simen Kjærås wrote:
> On Thursday, 15 March 2018 at 11:18:48 UTC, Robert-D wrote:
>> [...]
>
>
> This is where things go wrong:
>> [...]
>
> 'inout' means that this function can keep the const, immutable or mutable status of the type on which the function is called. This means that an inout function has to treat the object as const, because otherwise the function would break the guarantees of immutable and const.
>
> When using inout on a function, you always want to put inout on something else too - either a ref parameter or the return value. In your case, this works:
>
> inout(S) dup() inout pure {
> return inout(S)(aa);
> }
>
> --
> Simen
I want the function to create a mutable copy from a const or a imutable
Like this:
void main() {
const S s = S(["": ""]);
S b = s.dup();
}
How can i do that?
|
March 15, 2018 Re: Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert-D | On Thursday, 15 March 2018 at 12:00:08 UTC, Robert-D wrote: > I want the function to create a mutable copy from a const or a imutable > > Like this: > > void main() { > const S s = S(["": ""]); > S b = s.dup(); > } > > How can i do that? In that case, the problem is that you also have to .dup the aa: S dup() const pure { return S(aa.dup); } However, it seems aa.dup returns the wrong type - one would expect V[K] for inout(V[K]), but it returns inout(V)[K], or inout(string)[string], in your case. That's apparently a known bug: https://issues.dlang.org/show_bug.cgi?id=14148. The solution for now, then, is this: S dup() const pure { return S(cast(string[string])aa.dup); } -- Simen |
March 15, 2018 Re: Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Thursday, 15 March 2018 at 13:18:38 UTC, Simen Kjærås wrote: > On Thursday, 15 March 2018 at 12:00:08 UTC, Robert-D wrote: >> I want the function to create a mutable copy from a const or a imutable >> >> Like this: >> >> void main() { >> const S s = S(["": ""]); >> S b = s.dup(); >> } >> >> How can i do that? > > In that case, the problem is that you also have to .dup the aa: > > S dup() const pure { > return S(aa.dup); > } > > However, it seems aa.dup returns the wrong type - one would expect V[K] for inout(V[K]), but it returns inout(V)[K], or inout(string)[string], in your case. That's apparently a known bug: https://issues.dlang.org/show_bug.cgi?id=14148. > > The solution for now, then, is this: > > S dup() const pure { > return S(cast(string[string])aa.dup); > } > > -- > Simen 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); } } Error: static assert: "Cannot implicitly convert type inout(S) to S in dup." Or: const(S)[] ss = [S(["": ""])]; S[] d = ss.dup; Error: template object.dup cannot deduce function from argument types !()(const(S)[]), candidates are: /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(2086): object.dup(T : V[K], K, V)(T aa) /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(2122): object.dup(T : V[K], K, V)(T* aa) /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(4191): object.dup(T)(T[] a) if (!is(const(T) : T)) /dlang/dmd/linux/bin64/../../src/druntime/import/object.d(4207): object.dup(T)(const(T)[] a) if (is(const(T) : T)) |
March 15, 2018 Re: Error: cannot implicitly convert expression this.aa of type inout(string[string]) to string[string] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert-D | 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
|
Copyright © 1999-2021 by the D Language Foundation