digitalmars.D.learn - Template bug?
- Artyom Shalkhakov (32/32) Jan 29 2007 Hello everyone.
- Jarrett Billingsley (40/70) Jan 29 2007 There are a few things going wrong.
- Artyom Shalkhakov (6/106) Jan 29 2007 Thanks for your answer.
- Jarrett Billingsley (33/36) Jan 30 2007 Yep. You can do something like:
- Frits van Bommel (24/66) Jan 30 2007 static if + is-expressions (and creative 'alias' usage) clean that up
- Jarrett Billingsley (4/25) Jan 30 2007 Ahh, I was thinking about static if but thought that doing it for each
Hello everyone. I have a problem regarding D templates. This code doesn't work. I would like to know how do I get it up'n'running? struct temp_t( type ) { void setOwner( type *newOwner ) { owner = newOwner; } type *getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type * owner; } } class testClass_t { this( int d ) { data = d; tst.setOwner( &this ); } int data; temp_t!( testClass_t ) tst; } void foo() { testClass_t bar = new testClass_t( 0x1234 ); // what is the difference between '==' and 'is'? assert( ( *bar ).getOwner == bar ); // doesn't work } Can anyone tell me what is wrong? Thanks in advance. PS Excuse me for my English, as it's not my native language.
Jan 29 2007
"Artyom Shalkhakov" <artyom.sh gmail.ru> wrote in message news:epmho3$282d$1 digitaldaemon.com...Hello everyone. I have a problem regarding D templates. This code doesn't work. I would like to know how do I get it up'n'running? struct temp_t( type ) { void setOwner( type *newOwner ) { owner = newOwner; } type *getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type * owner; } } class testClass_t { this( int d ) { data = d; tst.setOwner( &this ); } int data; temp_t!( testClass_t ) tst; } void foo() { testClass_t bar = new testClass_t( 0x1234 ); // what is the difference between '==' and 'is'? assert( ( *bar ).getOwner == bar ); // doesn't work }There are a few things going wrong. One, when you write "tst.setOwner( &this );", this sets the owner to the address of a local variable. This is a Bad Thing. Remember that classes are reference types, so they are implicitly pointers. So instead of making your struct use pointers, just take all the *s out. struct temp_t( type ) { void setOwner( type newOwner ) { owner = newOwner; } type getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type owner; } } Then in your class's constructor, use tst.setOwner( this ); Lastly, this line: assert( ( *bar ).getOwner == bar ); Doesn't even compile because (1) you cannot dereference bar because it's not a pointer, it's a reference, and (2) there is no .getOwner property for the testClass_t class. Instead, you should use: assert( bar.tst.getOwner is bar); And that brings me to my last point, the difference between 'is' and '=='. 'is' is used to see if two references (or pointers) point to the same location. '==' is used to see if two things are equal. If you have two class references, a and b, and you write a == b This is the same as writing a.opEquals(b) If a is null, this will get you a segfault. However, if you just want to see if a and b are pointing to the same instance, use a is b Which is what you want to do in your example.
Jan 29 2007
Jarrett Billingsley Wrote:"Artyom Shalkhakov" <artyom.sh gmail.ru> wrote in message news:epmho3$282d$1 digitaldaemon.com...Thanks for your answer. Yes, it was my mistake to write it out like this:Hello everyone. I have a problem regarding D templates. This code doesn't work. I would like to know how do I get it up'n'running? struct temp_t( type ) { void setOwner( type *newOwner ) { owner = newOwner; } type *getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type * owner; } } class testClass_t { this( int d ) { data = d; tst.setOwner( &this ); } int data; temp_t!( testClass_t ) tst; } void foo() { testClass_t bar = new testClass_t( 0x1234 ); // what is the difference between '==' and 'is'? assert( ( *bar ).getOwner == bar ); // doesn't work }There are a few things going wrong. One, when you write "tst.setOwner( &this );", this sets the owner to the address of a local variable. This is a Bad Thing. Remember that classes are reference types, so they are implicitly pointers. So instead of making your struct use pointers, just take all the *s out. struct temp_t( type ) { void setOwner( type newOwner ) { owner = newOwner; } type getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type owner; } } Then in your class's constructor, use tst.setOwner( this ); Lastly, this line: assert( ( *bar ).getOwner == bar ); Doesn't even compile because (1) you cannot dereference bar because it's not a pointer, it's a reference, and (2) there is no .getOwner property for the testClass_t class. Instead, you should use: assert( bar.tst.getOwner is bar); And that brings me to my last point, the difference between 'is' and '=='. 'is' is used to see if two references (or pointers) point to the same location. '==' is used to see if two things are equal. If you have two class references, a and b, and you write a == b This is the same as writing a.opEquals(b) If a is null, this will get you a segfault. However, if you just want to see if a and b are pointing to the same instance, use a is b Which is what you want to do in your example.assert( ( *bar ).getOwner == bar );Well, this is my bug :) tst.setOwner( &this ); Okay, I've tried to use pointer to class because I intend to use this template for both structures and classes. How do I do that? Do I have to write template specialization?
Jan 29 2007
"Artyom Shalkhakov" <artyom.sh gmail.ru> wrote in message news:epmlh5$2crr$1 digitaldaemon.com...Okay, I've tried to use pointer to class because I intend to use this template for both structures and classes. How do I do that? Do I have to write template specialization?Yep. You can do something like: struct temp_t( type : Object ) { void setOwner( type newOwner ) { owner = newOwner; } type getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type owner; } } struct temp_t( type ) { void setOwner( type *newOwner ) { owner = newOwner; } type *getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type * owner; } } So it'll use the non-pointer version for classes (i.e. anything that derives from Object), and the pointer version for everything else.
Jan 30 2007
Jarrett Billingsley wrote:"Artyom Shalkhakov" <artyom.sh gmail.ru> wrote in message news:epmlh5$2crr$1 digitaldaemon.com...static if + is-expressions (and creative 'alias' usage) clean that up pretty well: ----- struct temp_t( type ) { static if(is(type == class)) alias type RefType; else alias type* RefType; void setOwner( RefType newOwner ) { owner = newOwner; } RefType getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; RefType owner; } } ----- Code duplication is ugly.Okay, I've tried to use pointer to class because I intend to use this template for both structures and classes. How do I do that? Do I have to write template specialization?Yep. You can do something like: struct temp_t( type : Object ) { void setOwner( type newOwner ) { owner = newOwner; } type getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type owner; } } struct temp_t( type ) { void setOwner( type *newOwner ) { owner = newOwner; } type *getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; type * owner; } }
Jan 30 2007
"Frits van Bommel" <fvbommel REMwOVExCAPSs.nl> wrote in message news:epnmuo$n9t$2 digitaldaemon.com...static if + is-expressions (and creative 'alias' usage) clean that up pretty well: ----- struct temp_t( type ) { static if(is(type == class)) alias type RefType; else alias type* RefType; void setOwner( RefType newOwner ) { owner = newOwner; } RefType getOwner() { return owner; } protected { temp_t * head; temp_t * next; temp_t * prev; RefType owner; } }Ahh, I was thinking about static if but thought that doing it for each member would have been ugly.. never thought about using an aliased type.
Jan 30 2007