Thread overview
Access outer member of struct from inner struct
Apr 02, 2019
Andrey
Apr 02, 2019
Q. Schroll
Apr 02, 2019
Jacob Carlborg
Apr 02, 2019
Q. Schroll
April 02, 2019
Hello,
In this example how can I access the members "read" and "q" of struct Outer from Inner struct?
> struct Outer
> {
> 	ulong q = 1;
>     Inner inner;
> 
>     void read(ulong value)
>     {
>         q += value;
>     }
> 
>     void run()
>     {
>     	q.writeln;
>         read(5);
>     }
> 
>     struct Inner
>     {
>      	void write(string text)
>         {
>             read(text.length);
>             writeln(q);
>         }
>     }
> }
> 
> void main()
> {
>     Outer ttt;
>     ttt.run();
> }

During compilation I get:
> onlineapp.d(55): Error: this for read needs to be type Outer not type Inner
> onlineapp.d(56): Error: need this for q of type ulong
April 02, 2019
On Tuesday, 2 April 2019 at 18:20:09 UTC, Andrey wrote:
> Hello,
> In this example how can I access the members "read" and "q" of struct Outer from Inner struct?
>> struct Outer
>> {
>> 	ulong q = 1;
>>     Inner inner;
>> 
>>     void read(ulong value)
>>     {
>>         q += value;
>>     }
>> 
>>     void run()
>>     {
>>     	q.writeln;
>>         read(5);
>>     }
>> 
>>     struct Inner
>>     {
>>      	void write(string text)
>>         {
>>             read(text.length);
>>             writeln(q);
>>         }
>>     }
>> }
>> 
>> void main()
>> {
>>     Outer ttt;
>>     ttt.run();
>> }
>
> During compilation I get:
>> onlineapp.d(55): Error: this for read needs to be type Outer not type Inner
>> onlineapp.d(56): Error: need this for q of type ulong

After removing the calls to writeln, the error I get is:

> `this` for `read` needs to be type `Outer` not type `Inner`

You cannot access stuff in Outer because Inner objects are not outer objects and don't implicitly own an Outer object. In your Inner method `write`, there is no Outer object present at all to call the method on.
April 02, 2019
On 2019-04-02 20:44, Q. Schroll wrote:

> After removing the calls to writeln, the error I get is:
> 
>> `this` for `read` needs to be type `Outer` not type `Inner`
> 
> You cannot access stuff in Outer because Inner objects are not outer objects and don't implicitly own an Outer object. In your Inner method `write`, there is no Outer object present at all to call the method on.

It works if the struct is nested inside a function [1]. I thought it would work nested inside a struct too.

[1] https://dlang.org/spec/struct.html#nested

-- 
/Jacob Carlborg
April 02, 2019
On Tuesday, 2 April 2019 at 18:52:07 UTC, Jacob Carlborg wrote:
> On 2019-04-02 20:44, Q. Schroll wrote:
>
>> After removing the calls to writeln, the error I get is:
>> 
>>> `this` for `read` needs to be type `Outer` not type `Inner`
>> 
>> You cannot access stuff in Outer because Inner objects are not outer objects and don't implicitly own an Outer object. In your Inner method `write`, there is no Outer object present at all to call the method on.
>
> It works if the struct is nested inside a function [1]. I thought it would work nested inside a struct too.
>
> [1] https://dlang.org/spec/struct.html#nested

The reason it works inside a function is that the struct has a hidden pointer to the function context. The function's local values actually exist when an object of that struct type is being instantiated.

The main difference between a struct nested in a function and one inside another struct is that the one in a function cannot¹ be created outside of that function while constructing the latter is possible the way you think it is:

Outer.Inner innerObj = Outer.Inner(parameters);

¹ You can using reflection and stuff like that, but it's still broken if it uses the context.