Thread overview
Struct template instancing inside of class failed
4 days ago
monkyyy
4 days ago
H. S. Teoh
4 days ago

Hi!

I'm not sure if this is an issue or if it was intended this way.

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?

4 days ago

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.

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

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.

4 days ago
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
4 days ago
On Friday, 2 May 2025 at 23:15:24 UTC, H. S. Teoh wrote:
>
> Try `S!(this.field)(777)` maybe?

I tried it - nothing changes

> 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?

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)

4 days ago

On Friday, 2 May 2025 at 22:51:24 UTC, monkyyy wrote:

> >

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

The main question for me is: why it worked for the class, but not for the struct?

>

it 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 with

The whole idea looks something like this:

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;
}
4 days ago
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