www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How to declare a parameterized recursive data structure?

reply "artemav" <im artemav.com> writes:
I'm getting an error when trying to compile (DMD64 D Compiler 
v2.066) this:

struct node(T) {
     T data;
     node!T next;
};

void main() {
     node!int n;
}

output:
test.d(3): Error: struct test.node!int.node cannot have field 
next with same struct type
test.d(9): Error: template instance test.node!int error 
instantiating
...

It is so simple code that the error "... cannot have field next 
with same struct type" looks funny and sad at the same time. Is 
it a bug or are there some constraints why it cannot be compiled?
Aug 15 2014
next sibling parent Justin Whear <justin economicmodeling.com> writes:
On Fri, 15 Aug 2014 18:37:51 +0000, artemav wrote:

 I'm getting an error when trying to compile (DMD64 D Compiler v2.066)
 this:
 
 struct node(T) {
      T data; node!T next;
 };
 
 void main() {
      node!int n;
 }
 
 output:
 test.d(3): Error: struct test.node!int.node cannot have field next with
 same struct type test.d(9): Error: template instance test.node!int error
 instantiating ...
 
 It is so simple code that the error "... cannot have field next with
 same struct type" looks funny and sad at the same time. Is it a bug or
 are there some constraints why it cannot be compiled?
You want `node!(T)* next`. Structs are POD types, not reference types, so the node struct would have a infinite regression.
Aug 15 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
artemav:

 struct node(T) {
     T data;
     node!T next;
 };
Try: struct node(T) { T data; node!T* next; } Bye, bearophile
Aug 15 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Aug 15, 2014 at 06:37:51PM +0000, artemav via Digitalmars-d wrote:
 I'm getting an error when trying to compile (DMD64 D Compiler v2.066) this:
 
 struct node(T) {
     T data;
     node!T next;
 };
 
 void main() {
     node!int n;
 }
 
 output:
 test.d(3): Error: struct test.node!int.node cannot have field next with same
 struct type
 test.d(9): Error: template instance test.node!int error instantiating
 ...
 
 It is so simple code that the error "... cannot have field next with
 same struct type" looks funny and sad at the same time. Is it a bug or
 are there some constraints why it cannot be compiled?
This has nothing to do with the struct being parametrized or not. Structs are value types, so defining a struct in terms of itself would make it infinitely large. That's why it's invalid. I'm guessing what you *really* want is to keep a pointer to another struct of the same type, in which case what you're looking for is: struct node(T) { T data; node* next; // Note: it's not necessary to specify // !T here, if you want, you can write // it as: node!T* next; } T -- Having a smoking section in a restaurant is like having a peeing section in a swimming pool. -- Edward Burr
Aug 15 2014
prev sibling next sibling parent reply "artemav" <im artemav.com> writes:
Sorry, jumped the gun on that.

On Friday, 15 August 2014 at 18:37:52 UTC, artemav wrote:
 I'm getting an error when trying to compile (DMD64 D Compiler 
 v2.066) this:

 struct node(T) {
     T data;
     node!T next;
 };

 void main() {
     node!int n;
 }

 output:
 test.d(3): Error: struct test.node!int.node cannot have field 
 next with same struct type
 test.d(9): Error: template instance test.node!int error 
 instantiating
 ...

 It is so simple code that the error "... cannot have field next 
 with same struct type" looks funny and sad at the same time. Is 
 it a bug or are there some constraints why it cannot be 
 compiled?
Aug 15 2014
parent reply "artemav" <im artemav.com> writes:
:) Wow, thanks for all replies. I realized too late that should 
write "that's it".
Hmm, It's also a good sign that D community is active.


On Friday, 15 August 2014 at 19:01:57 UTC, artemav wrote:
 Sorry, jumped the gun on that.

 On Friday, 15 August 2014 at 18:37:52 UTC, artemav wrote:
 I'm getting an error when trying to compile (DMD64 D Compiler 
 v2.066) this:

 struct node(T) {
    T data;
    node!T next;
 };

 void main() {
    node!int n;
 }

 output:
 test.d(3): Error: struct test.node!int.node cannot have field 
 next with same struct type
 test.d(9): Error: template instance test.node!int error 
 instantiating
 ...

 It is so simple code that the error "... cannot have field 
 next with same struct type" looks funny and sad at the same 
 time. Is it a bug or are there some constraints why it cannot 
 be compiled?
Aug 15 2014
parent Philippe Sigaud via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, Aug 15, 2014 at 9:13 PM, artemav via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 :) Wow, thanks for all replies. I realized too late that should write
 "that's it".
 Hmm, It's also a good sign that D community is active.
Can I add something? ;) You can also use a class, as they are reference types: class node(T) { T data; node next; } Or use a dynamic array if you want to define a tree: struct node(T) { T data; node[] children; }
Aug 15 2014
prev sibling parent reply "Gary Willoughby" <dev nomad.so> writes:
On Friday, 15 August 2014 at 18:37:52 UTC, artemav wrote:
 I'm getting an error when trying to compile (DMD64 D Compiler 
 v2.066) this:

 struct node(T) {
     T data;
     node!T next;
 };

 void main() {
     node!int n;
 }

 output:
 test.d(3): Error: struct test.node!int.node cannot have field 
 next with same struct type
 test.d(9): Error: template instance test.node!int error 
 instantiating
 ...

 It is so simple code that the error "... cannot have field next 
 with same struct type" looks funny and sad at the same time. Is 
 it a bug or are there some constraints why it cannot be 
 compiled?
Funnily enough i've been toying with linked lists using the same kind of nodes here: https://github.com/nomad-software/etcetera/blob/master/source/etcetera/collection/linkedlist.d Might be of use to you?
Aug 16 2014
parent reply "safety0ff" <safety0ff.dev gmail.com> writes:
On Saturday, 16 August 2014 at 17:55:28 UTC, Gary Willoughby
wrote:
 Funnily enough i've been toying with linked lists using the 
 same kind of nodes here:
 https://github.com/nomad-software/etcetera/blob/master/source/etcetera/collection/linkedlist.d

 Might be of use to you?
Why did you put the data between the two pointers? I would put the pointers side-by-side in memory: - The two pointers will be in the same cache line no matter which type T is used. - It should reduce the amount of padding in the Node struct.
Aug 16 2014
parent "Gary Willoughby" <dev nomad.so> writes:
On Saturday, 16 August 2014 at 22:55:37 UTC, safety0ff wrote:
 On Saturday, 16 August 2014 at 17:55:28 UTC, Gary Willoughby
 wrote:
 Funnily enough i've been toying with linked lists using the 
 same kind of nodes here:
 https://github.com/nomad-software/etcetera/blob/master/source/etcetera/collection/linkedlist.d

 Might be of use to you?
Why did you put the data between the two pointers? I would put the pointers side-by-side in memory: - The two pointers will be in the same cache line no matter which type T is used. - It should reduce the amount of padding in the Node struct.
Good idea, I didn't think about that.
Aug 17 2014