Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 30, 2007 Template bug? | ||||
---|---|---|---|---|
| ||||
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. |
January 30, 2007 Re: Template bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artyom Shalkhakov | "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. |
January 30, 2007 Re: Template bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley Wrote: > "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. > > Thanks for your answer. Yes, it was my mistake to write it out like this: >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? |
January 30, 2007 Re: Template bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artyom Shalkhakov | "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. |
January 30, 2007 Re: Template bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> "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;
> }
> }
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.
|
January 31, 2007 Re: Template bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | "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. |
Copyright © 1999-2021 by the D Language Foundation