www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - anonymous structs within structs

reply DLearner <bmqazwsx123 gmail.com> writes:
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?
Dec 04 2023
next sibling parent reply Mike Shah <mshah.475 gmail.com> writes:
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); } ```
Dec 04 2023
parent reply DLearner <bmqazwsx123 gmail.com> writes:
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.
Dec 04 2023
parent reply thinkunix <thinkunix zoho.com> writes:
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
Dec 04 2023
parent reply DLearner <bmqazwsx123 gmail.com> writes:
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.
Dec 04 2023
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
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...
Dec 04 2023
parent DLearner <bmqazwsx123 gmail.com> writes:
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.
Dec 05 2023
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Dec 05 2023