digitalmars.D - Struct template instancing inside of class failed
- Denis Feklushkin (49/49) May 02 Hi!
- monkyyy (13/62) May 02 Theres allot of spooky things here
- Denis Feklushkin (38/45) May 03 The main question for me is: why it worked for the class, but not
- H. S. Teoh (10/46) May 02 [...]
- Denis Feklushkin (9/15) May 03 This is a reduced example
- Denis Feklushkin (4/6) May 03 ...Then struct won't be able to know their own offset to access
Hi! I'm not sure if this is an issue or if it was intended this way. ```d class C(alias a) { pragma(msg, "class body: ", a.stringof); int internal; this(int unused){ pragma(msg, "class ctor: ", a.stringof); internal = a; } } struct S(alias a) { pragma(msg, "struct body:", a.stringof); int internal; this(int unused){ pragma(msg, "struct ctor:", a.stringof); internal = a; } } class Test { int field = 123; C!field c; S!field s; this(){ c = new C!field(777); // ok assert(c.internal == 123); // Error: accessing non-static variable `field` requires an instance of `Test` s = S!field(777); } } void main() { auto t = new Test; } ``` Compiler output: ``` class body: field struct body:field class ctor: this.this.field struct ctor:field app.d(20,20): Error: accessing non-static variable `field` requires an instance of `Test` internal = a; ^ Error dmd failed with exit code 1. ``` I suspect that class stores template parameter "a" in some hidden fields and this behaviour impossible for POD structs?
May 02
On Friday, 2 May 2025 at 21:58:50 UTC, Denis Feklushkin wrote:Hi! I'm not sure if this is an issue or if it was intended this way. ```d class C(alias a) { pragma(msg, "class body: ", a.stringof); int internal; this(int unused){ pragma(msg, "class ctor: ", a.stringof); internal = a; } } struct S(alias a) { pragma(msg, "struct body:", a.stringof); int internal; this(int unused){ pragma(msg, "struct ctor:", a.stringof); internal = a; } } class Test { int field = 123; C!field c; S!field s; this(){ c = new C!field(777); // ok assert(c.internal == 123); // Error: accessing non-static variable `field` requires an instance of `Test` s = S!field(777); } } void main() { auto t = new Test; } ``` Compiler output: ``` class body: field struct body:field class ctor: this.this.field struct ctor:field app.d(20,20): Error: accessing non-static variable `field` requires an instance of `Test` internal = a; ^ Error dmd failed with exit code 1. ``` I suspect that class stores template parameter "a" in some hidden fields and this behaviour impossible for POD structs?Theres allot of spooky things here it will compile if you add static to `static int field = 123;` if you want a spooky reference to a variable I suggest my "innate" code avoid this construction logic your playing with ```d template innate(T,T startingvalue=T.init,discrimination...){ T innate=startingvalue; } alias field=innate!(int,123,"field"); ``` if you dont need it run time you should pass ints to templates explictly where possible `struct S(int a) {` etc.
May 02
On Friday, 2 May 2025 at 22:51:24 UTC, monkyyy wrote:The main question for me is: why it worked for the class, but not for the struct?I suspect that class stores template parameter "a" in some hidden fields and this behaviour impossible for POD structs?Theres allot of spooky things hereit will compile if you add static to `static int field = 123;` if you want a spooky reference to a variable(Or function, or delegate)I suggest my "innate" code avoid this construction logic your playing withThe whole idea looks something like this: ```d struct S(alias outer_handler) { int internal_field = 1; this(int ctor_arg){ internal_field = ctor_arg; assert(outer_handler + internal_field == 124, "ctor failed"); } void someMethod() { assert(outer_handler + internal_field == 124, "method failed"); } ~this(){ // imitate some destruction process assert(outer_handler + internal_field == 124, "destruction failed"); } } class Test { int field = 123; ref getField() => field; alias S_Inst = S!getField; S_Inst s; this(){ // Error: calling non-static function `getField` requires an instance of type `Test` s = S_Inst(1); } } void main() { auto t = new Test; } ```
May 03
On Fri, May 02, 2025 at 09:58:50PM +0000, Denis Feklushkin via Digitalmars-d wrote:Hi! I'm not sure if this is an issue or if it was intended this way. ```d class C(alias a) { pragma(msg, "class body: ", a.stringof); int internal; this(int unused){ pragma(msg, "class ctor: ", a.stringof); internal = a; } } struct S(alias a) { pragma(msg, "struct body:", a.stringof); int internal; this(int unused){ pragma(msg, "struct ctor:", a.stringof); internal = a; } } class Test { int field = 123; C!field c; S!field s; this(){ c = new C!field(777); // ok assert(c.internal == 123); // Error: accessing non-static variable `field` requires an instance of `Test` s = S!field(777);[...] Try `S!(this.field)(777)` maybe? In any case, passing a class-local variable via an alias into a template parameter that tries to access it from inside a function seems rather dangerous and needlessly complex. Why not just pass the value directly, or a reference/pointer to the variable? T -- We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
May 02
On Friday, 2 May 2025 at 23:15:24 UTC, H. S. Teoh wrote:Try `S!(this.field)(777)` maybe?I tried it - nothing changesIn any case, passing a class-local variable via an alias into a template parameter that tries to access it from inside a function seems rather dangerous and needlessly complex. Why not just pass the value directly, or a reference/pointer to the variable?This is a reduced example IRL I need to pass some handler into methods and destructors of the structures that are stored in the array in class Test. There is no point in storing it in each instance of the structure - it is the same for all structures in the array. (Yes, of course I can write workarounds for all this, but I wanted to write this code idiomatically)
May 03
On Saturday, 3 May 2025 at 09:11:47 UTC, Denis Feklushkin wrote:IRL I need to pass some handler into methods and destructors of the structures that are stored in the array in class Test....Then struct won't be able to know their own offset to access to outer field because array can be of any size /thread
May 03