Thread overview
anonymous structs within structs
Dec 04, 2023
DLearner
Dec 04, 2023
Mike Shah
Dec 04, 2023
DLearner
Dec 04, 2023
thinkunix
Dec 04, 2023
DLearner
Dec 05, 2023
H. S. Teoh
Dec 05, 2023
DLearner
Dec 05, 2023
Jonathan M Davis
December 04, 2023

Suppose we need a construct like:

void main() {

   struct A {
      int I1;
      int I2;
      char X;
   }

   struct B {
      A Dummy;
      int Var1;
      int Var2;
   }
}

But do not want to give an explicit name (like 'Dummy' above) to the A struct held within the B struct.

Just removing 'Dummy' does not work (Error: no identifier for declarator A).
Nor does replacing 'Dummy' with {}

Suggestions?

December 04, 2023

On Monday, 4 December 2023 at 18:26:07 UTC, DLearner wrote:

>

Suppose we need a construct like:

void main() {

   struct A {
      int I1;
      int I2;
      char X;
   }

   struct B {
      A Dummy;
      int Var1;
      int Var2;
   }
}

But do not want to give an explicit name (like 'Dummy' above) to the A struct held within the B struct.

Just removing 'Dummy' does not work (Error: no identifier for declarator A).
Nor does replacing 'Dummy' with {}

Suggestions?

One possible solution is to use a 'mixin template' where you effectively 'copy and paste' in the 'struct' and access the symbols.

Is something like this what you had in mind?

void main() {
   import std.stdio;

   mixin template A() {
      int I1;
      int I2;
      char X;
   }

   struct B {
      mixin A;
      int Var1;
      int Var2;
   }

        B someObject;
        writeln(someObject.I1);
        writeln(someObject.I2);
}
December 04, 2023

On Monday, 4 December 2023 at 21:55:29 UTC, Mike Shah wrote:

[...]

>

Is something like this what you had in mind?

void main() {
   import std.stdio;

   mixin template A() {
      int I1;
      int I2;
      char X;
   }

   struct B {
      mixin A;
      int Var1;
      int Var2;
   }

        B someObject;
        writeln(someObject.I1);
        writeln(someObject.I2);
}

More like

B someObject;
         writeln(someObject.Var1);
         writeln(someObject.Var2);

In the areas where B is used, don't want I1 or I2 to be visible.

December 04, 2023
DLearner via Digitalmars-d-learn wrote:
> On Monday, 4 December 2023 at 21:55:29 UTC, Mike Shah wrote:
> 
> [...]
>>
>> Is something like this what you had in mind?
>>
>> ```
>> void main() {
>>    import std.stdio;
>>
>>    mixin template A() {
>>       int I1;
>>       int I2;
>>       char X;
>>    }
>>
>>    struct B {
>>       mixin A;
>>       int Var1;
>>       int Var2;
>>    }
>>
>>         B someObject;
>>         writeln(someObject.I1);
>>         writeln(someObject.I2);
>> }
>> ```
> 
> More like
> ```
> B someObject;
>           writeln(someObject.Var1);
>           writeln(someObject.Var2);
> ```
> 
> In the areas where B is used, don't want I1 or I2 to be visible.
> 

If you don't want members of A to be visible in B, why are you
even including struct A as part of B?

Why wouldn't you use a class and make the members private?

I'm certainly not a D expert and I don't know your use case
so maybe I'm missing something.

scot
December 04, 2023

On Monday, 4 December 2023 at 23:16:27 UTC, thinkunix wrote:

>

DLearner via Digitalmars-d-learn wrote:

>

On Monday, 4 December 2023 at 21:55:29 UTC, Mike Shah wrote:

[...]

>

Is something like this what you had in mind?

void main() {
   import std.stdio;

   mixin template A() {
      int I1;
      int I2;
      char X;
   }

   struct B {
      mixin A;
      int Var1;
      int Var2;
   }

        B someObject;
        writeln(someObject.I1);
        writeln(someObject.I2);
}

More like

B someObject;
          writeln(someObject.Var1);
          writeln(someObject.Var2);

In the areas where B is used, don't want I1 or I2 to be visible.

If you don't want members of A to be visible in B, why are you
even including struct A as part of B?

Why wouldn't you use a class and make the members private?

I'm certainly not a D expert and I don't know your use case
so maybe I'm missing something.

scot

Basically, B corresponds to the whole record (and only a whole record can be read).
But the task only requires Var1 and Var2, the last two fields on the record.
By putting all the irrelevant fields into A, and defining B as above,
program remains unpolluted with data it does not need.

December 04, 2023
On Mon, Dec 04, 2023 at 11:46:45PM +0000, DLearner via Digitalmars-d-learn wrote: [...]
> Basically, B corresponds to the whole record (and only a whole record
> can be read).
> But the task only requires Var1 and Var2, the last two fields on the record.
> By putting all the irrelevant fields into A, and defining B as above,
> program remains unpolluted with data it does not need.
[...]

Sounds like what you need is something like this:

	struct Record {
		struct UnimportantStuff {
			...
		}
		UnimportantStuff unimportant;

		struct ImportantStuff {
			...
		}
		ImportantStuff important;
	}

	ImportantStuff readData() {
		Record rec = readData(...); // read entire record
		return rec.important; // discard unimportant stuff
	}

	int main() {
		...
		ImportantStuff data = readData(); // only important stuff returned
		processData(data);
		...
	}


T

-- 
Let X be the set not defined by this sentence...
December 05, 2023

On Tuesday, 5 December 2023 at 00:31:35 UTC, H. S. Teoh wrote:

>

On Mon, Dec 04, 2023 at 11:46:45PM +0000, DLearner via Digitalmars-d-learn wrote: [...]

>

Basically, B corresponds to the whole record (and only a whole record
can be read).
But the task only requires Var1 and Var2, the last two fields on the record.
By putting all the irrelevant fields into A, and defining B as above,
program remains unpolluted with data it does not need.
[...]

Sounds like what you need is something like this:

struct Record {
struct UnimportantStuff {
...
}
UnimportantStuff unimportant;

  struct ImportantStuff {
  	...
  }
  ImportantStuff important;

}

ImportantStuff readData() {
Record rec = readData(...); // read entire record
return rec.important; // discard unimportant stuff
}

int main() {
...
ImportantStuff data = readData(); // only important stuff returned
processData(data);
...
}

T

I think that what you propose would work.

However, what I was really interested in was finding a way (using your example) of not instantiating UnimportantStuff anywhere.

Your suggestion instantiates it at:

UnimportantStuff unimportant;

I was thinking (again using your example) of something like:

   struct UnimportantStuff {
			...
	}

	struct Record {
		UnimportantStuff.sizeof;

		struct ImportantStuff {
			...
		}
		ImportantStuff important;
	}

But was concerned about possible alignment issues.

December 05, 2023
On Monday, December 4, 2023 11:26:07 AM MST DLearner via Digitalmars-d-learn wrote:
> Suppose we need a construct like:
> ```
> void main() {
>
>     struct A {
>        int I1;
>        int I2;
>        char X;
>     }
>
>     struct B {
>        A Dummy;
>        int Var1;
>        int Var2;
>     }
> }
> ```
> But do not want to give an explicit name (like 'Dummy' above) to
> the A struct held within the B struct.
>
> Just removing 'Dummy' does not work (Error: no identifier for
> declarator `A`).
> Nor does replacing 'Dummy' with {}
>
> Suggestions?

Normally, if you're not going to actually use the member variables, then there's no point in them even being there. However, if you need them there for alignment purposes, then you can just make them private.

- Jonathan M Davis