Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
July 07, 2014 Sparse Aggregate Assignment/Initialization (RAII) | ||||
---|---|---|---|---|
| ||||
Because D currently doesn't support RAII using named parameters like in Python I tried the following. Say I have an aggregate class C { int x,y,z,w; } or similarly struct C { int x,y,z,w; } I know define a generic _free_ function ref T set(string member, T, U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, member)) { mixin(`a.` ~ member ~ ` = value;`); return a; } which I want to use for flexible initialization of several members at once. However using this function through UFCS auto cx = new C().set!"x"(11); fails as algorithm_ex.d(1257,17): Error: template algorithm_ex.set cannot deduce function from argument types !("x")(C, int), candidates are: algorithm_ex.d(1242,7): algorithm_ex.set(string member, T, U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, member)) Instead I have to use auto c = new C(); set!"x"(c, 11); which is not as elegant. Why doesn't UCFS work here and is there a solution using DMD git master? Further Is there a cleverer way to do this without resorting to mixins? This old post http://forum.dlang.org/thread/mailman.2966.1301533296.4748.digitalmars-d-learn@puremagic.com talks about opDispatch() but, to my knowledge, it requires the aggregate to have extra members doing the initialization. I want this because I've identified in some parts of my code that I have large structures were only a few of the elements are initialized to non-default values. |
July 07, 2014 Re: Sparse Aggregate Assignment/Initialization (RAII) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Mon, 07 Jul 2014 21:34:05 +0000, Nordlöw wrote: > However using this function through UFCS > > auto cx = new C().set!"x"(11); > > fails as > > algorithm_ex.d(1257,17): Error: template algorithm_ex.set cannot deduce > function from argument types !("x")(C, int), candidates are: > algorithm_ex.d(1242,7): algorithm_ex.set(string member, T, > U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, > member)) > > Instead I have to use > > auto c = new C(); set!"x"(c, 11); > > which is not as elegant. > > Why doesn't UCFS work here and is there a solution using DMD git master? You need to use `auto ref` to have this work with both classes and structs. A working version of your code here: auto dx = D().set!"x"(11); assert(dx.x == 11); On Mon, 07 Jul 2014 21:34:05 +0000, Nordlöw wrote: > Further Is there a cleverer way to do this without resorting to mixins? __traits(getMember, ...) is useful here, see this version of your code: http://dpaste.dzfl.pl/75e03fbec020 |
July 07, 2014 Re: Sparse Aggregate Assignment/Initialization (RAII) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Justin Whear | On Mon, 07 Jul 2014 21:49:22 +0000, Justin Whear wrote: > On Mon, 07 Jul 2014 21:34:05 +0000, Nordlöw wrote: > >> However using this function through UFCS >> >> auto cx = new C().set!"x"(11); >> >> fails as >> >> algorithm_ex.d(1257,17): Error: template algorithm_ex.set cannot deduce >> function from argument types !("x")(C, int), candidates are: >> algorithm_ex.d(1242,7): algorithm_ex.set(string member, T, >> U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, >> member)) >> >> Instead I have to use >> >> auto c = new C(); set!"x"(c, 11); >> >> which is not as elegant. >> >> Why doesn't UCFS work here and is there a solution using DMD git master? > > You need to use `auto ref` to have this work with both classes and > structs. A working version of your code here: auto dx = > D().set!"x"(11); > assert(dx.x == 11); Copy and paste gone astray; should be this link: http://dpaste.dzfl.pl/3c33ad70040f |
July 08, 2014 Re: Sparse Aggregate Assignment/Initialization (RAII) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Justin Whear | On Monday, 7 July 2014 at 21:50:22 UTC, Justin Whear wrote:
> Copy and paste gone astray; should be this link:
> http://dpaste.dzfl.pl/3c33ad70040f
Thx!
|
July 08, 2014 Re: Sparse Aggregate Assignment/Initialization (RAII) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Justin Whear | On Monday, 7 July 2014 at 21:49:22 UTC, Justin Whear wrote:
> On Mon, 07 Jul 2014 21:34:05 +0000, Nordlöw wrote:
>
>> However using this function through UFCS
>>
>> auto cx = new C().set!"x"(11);
>>
>> fails as
>>
>> algorithm_ex.d(1257,17): Error: template algorithm_ex.set cannot deduce
>> function from argument types !("x")(C, int), candidates are:
>> algorithm_ex.d(1242,7): algorithm_ex.set(string member, T,
>> U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T,
>> member))
>>
>> Instead I have to use
>>
>> auto c = new C(); set!"x"(c, 11);
>>
>> which is not as elegant.
>>
>> Why doesn't UCFS work here and is there a solution using DMD git master?
>
> You need to use `auto ref` to have this work with both classes and
> structs. A working version of your code here: auto dx = D().set!"x"(11);
> assert(dx.x == 11);
To elaborate:
`new C()` is an r-value, and references can only be taken from l-values.
|
Copyright © 1999-2021 by the D Language Foundation