Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 21, 2004 typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
I was hoping to use a simple method to determine the real typeid of a variable at runtime using the code example below...
<code>
class GenClass {}
class Foo: GenClass {}
class Bar: GenClass {}
void main()
{
GenClass a = new Foo;
GenClass b = new Bar;
if (typeid(a) is typeid(Foo))
printf("a is a Foo\n");
}
</code>
But this fails to compile, giving the error message "test2.d(12): a is used as a type". Which is exactly as the specification says it should.
So I did get a workaround going by doing this ...
<code>
class GenClass { abstract TypeInfo datatype();}
class Foo: GenClass { TypeInfo datatype() { return typeid(Foo);} }
class Bar: GenClass { TypeInfo datatype() { return typeid(Bar);} }
void main()
{
GenClass f = new Foo;
GenClass b = new Bar;
if (f.datatype is typeid(Foo))
printf("f is a Foo\n");
if (b.datatype is typeid(Bar))
printf("b is a Bar\n");
}
</code>
I also tried an alternative workaround, which also worked ...
<code>
class GenClass: ClassInfo {this(){name = "GenClass";}}
class Foo: GenClass { this(){name = "Foo";} }
class Bar: GenClass { this(){name = "Bar";} }
void main()
{
GenClass f = new Foo;
GenClass b = new Bar;
GenClass g = new GenClass;
printf("f is a %.*s\n", f.name);
printf("b is a %.*s\n", b.name);
printf("g is a %.*s\n", g.name);
}
</code>
but this doesn't make GenClass an abstract one.
So (finally) my questions are ... Is there a better way to do this sort of thing, and if not, which of the two ways above is better?
--
Derek
Melbourne, Australia
21/Jul/04 11:29:24 AM
|
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | How about... class GenClass {} class Foo: GenClass {} class Bar: GenClass {} void main() { GenClass a = new Foo; GenClass b = new Bar; if (cast(Foo)a) printf("a is a Foo\n"); if (cast(Foo)b) printf("b is a Foo\n"); if (cast(Bar)a) printf("a is a Bar\n"); if (cast(Bar)b) printf("b is a Bar\n"); } Regan On Wed, 21 Jul 2004 11:43:09 +1000, Derek Parnell <derek@psych.ward> wrote: > I was hoping to use a simple method to determine the real typeid of a > variable at runtime using the code example below... > > <code> > class GenClass {} > > class Foo: GenClass {} > > class Bar: GenClass {} > > void main() > { > GenClass a = new Foo; > GenClass b = new Bar; > > if (typeid(a) is typeid(Foo)) > printf("a is a Foo\n"); > } > </code> > > But this fails to compile, giving the error message "test2.d(12): a is used > as a type". Which is exactly as the specification says it should. > > So I did get a workaround going by doing this ... > > <code> > class GenClass { abstract TypeInfo datatype();} > > class Foo: GenClass { TypeInfo datatype() { return typeid(Foo);} } > > class Bar: GenClass { TypeInfo datatype() { return typeid(Bar);} } > > void main() > { > GenClass f = new Foo; > GenClass b = new Bar; > > if (f.datatype is typeid(Foo)) > printf("f is a Foo\n"); > if (b.datatype is typeid(Bar)) > printf("b is a Bar\n"); > } > </code> > > I also tried an alternative workaround, which also worked ... > > <code> > class GenClass: ClassInfo {this(){name = "GenClass";}} > > class Foo: GenClass { this(){name = "Foo";} } > > class Bar: GenClass { this(){name = "Bar";} } > > void main() > { > GenClass f = new Foo; > GenClass b = new Bar; > GenClass g = new GenClass; > > printf("f is a %.*s\n", f.name); > printf("b is a %.*s\n", b.name); > printf("g is a %.*s\n", g.name); > } > </code> > > but this doesn't make GenClass an abstract one. > > So (finally) my questions are ... Is there a better way to do this sort of > thing, and if not, which of the two ways above is better? > -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | On Wed, 21 Jul 2004 13:57:20 +1200, Regan Heath wrote: > How about... > > class GenClass {} > > class Foo: GenClass {} > > class Bar: GenClass {} > > void main() > { > GenClass a = new Foo; > GenClass b = new Bar; > > if (cast(Foo)a) printf("a is a Foo\n"); > if (cast(Foo)b) printf("b is a Foo\n"); > if (cast(Bar)a) printf("a is a Bar\n"); > if (cast(Bar)b) printf("b is a Bar\n"); > } > Thanks. This is almost right for me. I didn't realize that 'cast' returns a NULL if it fails to cast correctly. Anyhow, this is almost right except that it can still produce some ambiguous results... if (cast(GenClass)b) printf("b is a GenClass\n"); if (cast(Bar)b) printf("b is a Bar\n"); Thus 'b' is reported as being both 'GenClass' and 'Bar'. Whereas I think that 'b' *is* specifically (or more precisely) a 'Bar', but it is only a type of 'GenClass'. The method's I tried would only report it as being one type of class without ambiguity. But thanks for the info. -- Derek Melbourne, Australia 21/Jul/04 12:41:23 PM |
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | On Wed, 21 Jul 2004 12:47:12 +1000, Derek Parnell <derek@psych.ward> wrote: > On Wed, 21 Jul 2004 13:57:20 +1200, Regan Heath wrote: > >> How about... >> >> class GenClass {} >> >> class Foo: GenClass {} >> >> class Bar: GenClass {} >> >> void main() >> { >> GenClass a = new Foo; >> GenClass b = new Bar; >> >> if (cast(Foo)a) printf("a is a Foo\n"); >> if (cast(Foo)b) printf("b is a Foo\n"); >> if (cast(Bar)a) printf("a is a Bar\n"); >> if (cast(Bar)b) printf("b is a Bar\n"); >> } >> > > Thanks. This is almost right for me. I didn't realize that 'cast' returns a > NULL if it fails to cast correctly. Anyhow, this is almost right except > that it can still produce some ambiguous results... > > if (cast(GenClass)b) printf("b is a GenClass\n"); > if (cast(Bar)b) printf("b is a Bar\n"); > > Thus 'b' is reported as being both 'GenClass' and 'Bar'. Whereas I think > that 'b' *is* specifically (or more precisely) a 'Bar', but it is only a > type of 'GenClass'. 'b' itself is a reference to a GenClass. The thing it references is a Bar. It would be nice to be able to get those two pieces of info, at present we only get the type of the reference eg. "typeid(typeof(b)) is typeid(GenClass)" > The method's I tried would only report it as being one type of class > without ambiguity. Can I ask why you need this? For logging purposes perhaps? Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote: > I was hoping to use a simple method to determine the real typeid of a > variable at runtime using the code example below... > > <code> > class GenClass {} > > class Foo: GenClass {} > > class Bar: GenClass {} > > void main() > { > GenClass a = new Foo; > GenClass b = new Bar; > > if (typeid(a) is typeid(Foo)) This is as simple as it gets: if (typeid(typeof(a)) is typeid(Foo)) > printf("a is a Foo\n"); > } > </code> > > But this fails to compile, giving the error message "test2.d(12): a is used > as a type". Which is exactly as the specification says it should. > > So I did get a workaround going by doing this ... > > <code> > class GenClass { abstract TypeInfo datatype();} > > class Foo: GenClass { TypeInfo datatype() { return typeid(Foo);} } > > class Bar: GenClass { TypeInfo datatype() { return typeid(Bar);} } > > void main() > { > GenClass f = new Foo; > GenClass b = new Bar; > > if (f.datatype is typeid(Foo)) > printf("f is a Foo\n"); > if (b.datatype is typeid(Bar)) > printf("b is a Bar\n"); > } > </code> > > I also tried an alternative workaround, which also worked ... > > <code> > class GenClass: ClassInfo {this(){name = "GenClass";}} > > class Foo: GenClass { this(){name = "Foo";} } > > class Bar: GenClass { this(){name = "Bar";} } > > void main() > { > GenClass f = new Foo; > GenClass b = new Bar; > GenClass g = new GenClass; > > printf("f is a %.*s\n", f.name); > printf("b is a %.*s\n", b.name); > printf("g is a %.*s\n", g.name); > } > </code> > > but this doesn't make GenClass an abstract one. > > So (finally) my questions are ... Is there a better way to do this sort of > thing, and if not, which of the two ways above is better? > |
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | On Wed, 21 Jul 2004 15:19:37 +1200, Regan Heath wrote: > On Wed, 21 Jul 2004 12:47:12 +1000, Derek Parnell <derek@psych.ward> wrote: >> On Wed, 21 Jul 2004 13:57:20 +1200, Regan Heath wrote: >> >>> How about... >>> >>> class GenClass {} >>> >>> class Foo: GenClass {} >>> >>> class Bar: GenClass {} >>> >>> void main() >>> { >>> GenClass a = new Foo; >>> GenClass b = new Bar; >>> >>> if (cast(Foo)a) printf("a is a Foo\n"); >>> if (cast(Foo)b) printf("b is a Foo\n"); >>> if (cast(Bar)a) printf("a is a Bar\n"); >>> if (cast(Bar)b) printf("b is a Bar\n"); >>> } >>> >> >> Thanks. This is almost right for me. I didn't realize that 'cast' >> returns a >> NULL if it fails to cast correctly. Anyhow, this is almost right except >> that it can still produce some ambiguous results... >> >> if (cast(GenClass)b) printf("b is a GenClass\n"); >> if (cast(Bar)b) printf("b is a Bar\n"); >> >> Thus 'b' is reported as being both 'GenClass' and 'Bar'. Whereas I think that 'b' *is* specifically (or more precisely) a 'Bar', but it is only a type of 'GenClass'. > > 'b' itself is a reference to a GenClass. The thing it references is a Bar. It would be nice to be able to get those two pieces of info, at present we only get the type of the reference eg. "typeid(typeof(b)) is typeid(GenClass)" Yeah I tried that too, but as you hinted, its usage is a bit limited. Interestingly, if you do something like ... GenClass b = new Bar; GenClass gc; gc = cast(GenClass)b; then you can still access the Bar members that override GenClass members via 'gc' even though 'gc' is not a Bar class. In other words, cast does not actually *convert* it to a GenClass, it just let's the compiler pretend that is a GenClass but its still really a Bar. >> The method's I tried would only report it as being one type of class without ambiguity. > > Can I ask why you need this? For logging purposes perhaps? I'm working on a 'compiler' for the Euphoria programming language that will use D as the intermediate language. Eu --> D --> obj --> exe. Euphoria supports 'variant' type variables and I'm experimenting with different ways to implement these in D. I have one implementation that works very well, and now I'm trying out some optimizations. -- Derek Melbourne, Australia 21/Jul/04 1:56:34 PM |
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Edwards | On Wed, 21 Jul 2004 00:13:25 -0400, Andrew Edwards wrote: > Derek Parnell wrote: >> I was hoping to use a simple method to determine the real typeid of a variable at runtime using the code example below... >> >> <code> >> class GenClass {} >> >> class Foo: GenClass {} >> >> class Bar: GenClass {} >> >> void main() >> { >> GenClass a = new Foo; >> GenClass b = new Bar; >> >> if (typeid(a) is typeid(Foo)) > > This is as simple as it gets: > if (typeid(typeof(a)) is typeid(Foo)) > printf("a is a Foo\n"); Except that this doesn't work as expected. 'typeid(typeof(a))' returns 'typeid(GenClass)' and not 'typeid(Foo)'. -- Derek Melbourne, Australia 21/Jul/04 2:25:15 PM |
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> On Wed, 21 Jul 2004 00:13:25 -0400, Andrew Edwards wrote:
>
>
>>Derek Parnell wrote:
>>
>>>I was hoping to use a simple method to determine the real typeid of a
>>>variable at runtime using the code example below...
>>>
>>><code>
>>> class GenClass {}
>>>
>>> class Foo: GenClass {}
>>>
>>> class Bar: GenClass {}
>>>
>>> void main()
>>> {
>>> GenClass a = new Foo;
>>> GenClass b = new Bar;
>>>
>>> if (typeid(a) is typeid(Foo))
>>
>>This is as simple as it gets:
>> if (typeid(typeof(a)) is typeid(Foo))
>> printf("a is a Foo\n");
>
>
> Except that this doesn't work as expected.
>
> 'typeid(typeof(a))' returns 'typeid(GenClass)' and not 'typeid(Foo)'.
>
I C. Thanks for the clarification!
|
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | On Wed, 21 Jul 2004 14:21:11 +1000, Derek Parnell <derek@psych.ward> wrote: > On Wed, 21 Jul 2004 15:19:37 +1200, Regan Heath wrote: > >> On Wed, 21 Jul 2004 12:47:12 +1000, Derek Parnell <derek@psych.ward> wrote: >>> On Wed, 21 Jul 2004 13:57:20 +1200, Regan Heath wrote: >>> >>>> How about... >>>> >>>> class GenClass {} >>>> >>>> class Foo: GenClass {} >>>> >>>> class Bar: GenClass {} >>>> >>>> void main() >>>> { >>>> GenClass a = new Foo; >>>> GenClass b = new Bar; >>>> >>>> if (cast(Foo)a) printf("a is a Foo\n"); >>>> if (cast(Foo)b) printf("b is a Foo\n"); >>>> if (cast(Bar)a) printf("a is a Bar\n"); >>>> if (cast(Bar)b) printf("b is a Bar\n"); >>>> } >>>> >>> >>> Thanks. This is almost right for me. I didn't realize that 'cast' >>> returns a >>> NULL if it fails to cast correctly. Anyhow, this is almost right except >>> that it can still produce some ambiguous results... >>> >>> if (cast(GenClass)b) printf("b is a GenClass\n"); >>> if (cast(Bar)b) printf("b is a Bar\n"); >>> >>> Thus 'b' is reported as being both 'GenClass' and 'Bar'. Whereas I think >>> that 'b' *is* specifically (or more precisely) a 'Bar', but it is only a >>> type of 'GenClass'. >> >> 'b' itself is a reference to a GenClass. The thing it references is a Bar. >> It would be nice to be able to get those two pieces of info, at present we >> only get the type of the reference eg. "typeid(typeof(b)) is >> typeid(GenClass)" > > > Yeah I tried that too, but as you hinted, its usage is a bit limited. > Interestingly, if you do something like ... > > GenClass b = new Bar; > GenClass gc; > > gc = cast(GenClass)b; You don't need the cast. This > gc = b; works. > then you can still access the Bar members that override GenClass members > via 'gc' even though 'gc' is not a Bar class. Neither is 'b'. Both of them are GenClass _references_ to _something_ which must be a GenClass or one of it's derivatives. > In other words, cast does not > actually *convert* it to a GenClass, it just let's the compiler pretend > that is a GenClass but its still really a Bar. I think it's more that a GenClass reference, when it refers to a derivative of GenClass can access that derivatives members. >>> The method's I tried would only report it as being one type of class >>> without ambiguity. >> >> Can I ask why you need this? For logging purposes perhaps? > > I'm working on a 'compiler' for the Euphoria programming language that will > use D as the intermediate language. Eu --> D --> obj --> exe. Euphoria > supports 'variant' type variables and I'm experimenting with different ways > to implement these in D. I have one implementation that works very well, > and now I'm trying out some optimizations. That sounds quite cool. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
July 21, 2004 Re: typeid( identifier ) usage | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | On Wed, 21 Jul 2004 14:27:57 +1000, Derek Parnell <derek@psych.ward> wrote: > On Wed, 21 Jul 2004 00:13:25 -0400, Andrew Edwards wrote: > >> Derek Parnell wrote: >>> I was hoping to use a simple method to determine the real typeid of a >>> variable at runtime using the code example below... >>> >>> <code> >>> class GenClass {} >>> >>> class Foo: GenClass {} >>> >>> class Bar: GenClass {} >>> >>> void main() >>> { >>> GenClass a = new Foo; >>> GenClass b = new Bar; >>> >>> if (typeid(a) is typeid(Foo)) >> >> This is as simple as it gets: >> if (typeid(typeof(a)) is typeid(Foo)) >> printf("a is a Foo\n"); > > Except that this doesn't work as expected. > > 'typeid(typeof(a))' returns 'typeid(GenClass)' and not 'typeid(Foo)'. Technically 'a' is a GenClass _reference_ so typeof(a) should return 'GenClass'. What you really want to be able to ask is "what type does 'a' refer to?" Take 'int' and 'int*' for example int a; int *b = &a; typeof(a) is 'int' typeof(b) is 'int*' typeof(*b) is 'int' you can't do the same with a class reference however. :) Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/ |
Copyright © 1999-2021 by the D Language Foundation