Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 28, 2014 How to use the result of __traits( allMembers , T ) with string mixins ? | ||||
---|---|---|---|---|
| ||||
DMD tells me "Error: variable m cannot be read at compile time", but why ? [code] struct MyStruct { float float_value = 0.0f ; ubyte ubyte_value = 2 ; } enum members = [ __traits( allMembers , MyStruct ) ] ; foreach( m ; members ) { mixin( "writeln( " ~ m ~ " , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) ;" ) ; } [\code] I also tried ref m and foreach( i ; 0..members.length ) with m[i]. A simple writeln( m or m[i] ) always worked. I read the limitation of "String Mixins and Compile Time Function Execution" here: http://dlang.org/function.html#interpretation But it doesn't make sense to me as members are enum values and known at compile time. What am I doing wrong, and how could it be done ? Regards, ParticlePeter |
April 28, 2014 Re: How to use the result of __traits( allMembers , T ) with string mixins ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ParticlePeter | On Monday, 28 April 2014 at 13:52:52 UTC, ParticlePeter wrote:
> DMD tells me "Error: variable m cannot be read at compile time", but why ?
Because 'static foreach' is not an explicit feature yet, so it depends on the context. When you wrap the trait via:
[__traits(allMembers, MyStruct)]
You're creating an array, and foreach will *not* by default attempt to become a static foreach, even if the array is known at compile-time. If you remove the parentheses it will work. You've had a few bugs in the mixin code though, anyway here's the working sample:
-----
import std.stdio;
struct MyStruct
{
float float_value = 0.0f;
ubyte ubyte_value = 2;
}
enum members = __traits(allMembers, MyStruct);
void main()
{
foreach (m; members)
{
mixin("writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) );");
}
}
-----
|
April 28, 2014 Re: How to use the result of __traits( allMembers , T ) with string mixins ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Monday, 28 April 2014 at 13:57:56 UTC, Andrej Mitrovic wrote:
> On Monday, 28 April 2014 at 13:52:52 UTC, ParticlePeter wrote:
>> DMD tells me "Error: variable m cannot be read at compile time", but why ?
>
> Because 'static foreach' is not an explicit feature yet, so it depends on the context. When you wrap the trait via:
>
> [__traits(allMembers, MyStruct)]
>
> You're creating an array, and foreach will *not* by default attempt to become a static foreach, even if the array is known at compile-time. If you remove the parentheses it will work. You've had a few bugs in the mixin code though, anyway here's the working sample:
>
> -----
> import std.stdio;
>
> struct MyStruct
> {
> float float_value = 0.0f;
> ubyte ubyte_value = 2;
> }
>
> enum members = __traits(allMembers, MyStruct);
>
> void main()
> {
> foreach (m; members)
> {
> mixin("writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) );");
> }
> }
> -----
Thank you very much, it works. I never came so far to see those mixin errors at all :-)
I found the code with parenthesis in the dlang __traits docs and also Philippe Sigauds "D Templates", and I haven't seen any other example which works without them. So, when to use which syntax ( for which purpose ) ? Is this clarified somewhere ?
Regards, ParticlePeter
|
April 28, 2014 Re: How to use the result of __traits( allMembers , T ) with string mixins ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ParticlePeter | On 4/28/14, ParticlePeter via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > I found the code with parenthesis in the dlang __traits docs and also Philippe Sigauds "D Templates", and I haven't seen any other example which works without them. So, when to use which syntax ( for which purpose ) ? If you need to store the tuple as an array to some variable, then you would use that syntax. It all depends on what you're trying to do from the call site. Ultimately it won't matter much once we finally get a proper 'static foreach' feature in D. |
April 28, 2014 Re: How to use the result of __traits( allMembers , T ) with string mixins ? | ||||
---|---|---|---|---|
| ||||
On Mon, Apr 28, 2014 at 5:45 PM, Andrej Mitrovic via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > If you need to store the tuple as an array to some variable, then you would use that syntax. It all depends on what you're trying to do from the call site. Ultimately it won't matter much once we finally get a proper 'static foreach' feature in D. I guess a common use case is to create an array with [__traits(...)], and use it inside a function, iterating on it and creating a string with the elements. The string is then mixed in with a CTFE call. string makeCode(...) { enum members = [ __traits(allMembers, MyStruct) ]; string result; foreach (m; members) { result ~= "writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) );"); } return result; } mixin(makeCode()); I don't know what I used it for in the tutorial, though :-) |
April 28, 2014 Re: How to use the result of __traits( allMembers , T ) with string mixins ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | On Monday, 28 April 2014 at 17:40:54 UTC, Philippe Sigaud via Digitalmars-d-learn wrote:
> On Mon, Apr 28, 2014 at 5:45 PM, Andrej Mitrovic via
> Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>
>> If you need to store the tuple as an array to some variable, then you
>> would use that syntax. It all depends on what you're trying to do from
>> the call site. Ultimately it won't matter much once we finally get a
>> proper 'static foreach' feature in D.
>
> I guess a common use case is to create an array with [__traits(...)],
> and use it inside a function, iterating on it and creating a string
> with the elements. The string is then mixed in with a CTFE call.
>
> string makeCode(...) {
> enum members = [ __traits(allMembers, MyStruct) ];
>
> string result;
> foreach (m; members)
> {
> result ~= "writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~
> ".offsetof ) );");
> }
> return result;
> }
>
> mixin(makeCode());
>
> I don't know what I used it for in the tutorial, though :-)
You can do the same iterating directly over allMembers list, why would you prefer array here?
|
April 28, 2014 Re: How to use the result of __traits( allMembers , T ) with string mixins ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Mon, Apr 28, 2014 at 8:20 PM, Dicebot via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > You can do the same iterating directly over allMembers list, why would you prefer array here? Hmm, indeed. One advantage would be to get a range, and thus the power and filtering, mapping and co. |
Copyright © 1999-2021 by the D Language Foundation