Jump to page: 1 2
Thread overview
rtti cast
May 01, 2008
Simon Buerger
May 01, 2008
BCS
May 01, 2008
Simon Buerger
May 02, 2008
terranium
May 02, 2008
Pragma
May 02, 2008
terranium
May 02, 2008
BCS
May 07, 2008
terranium
May 07, 2008
BCS
May 05, 2008
Leandro Lucarella
May 02, 2008
Robert Fraser
May 04, 2008
downs
May 01, 2008
hi
I would like to do some RTTI, but not with type-IDs, but in some more pretty way. I'll simply post some code to show you what I mean :) . My Question is now: Does anyone know, how to do sth alike with the current D implementation (maybe with templates, but I dont see a nice way) ? Or do you think it could be worth an extension for D 2.0 ?
Krox

Code:

class Base {}
class A : Base
{
	void function_A() { ... }
}
class B : Base {}
{
	void function_B() { ... }
}

void main()
{
	Base x = ...
	
	// checks if x is of type A, and if so, declares y as A alias of x with other type
	if (x == A y)	
		y.function_A();
	else if(x == B y)
		y.function_B();
}
May 01, 2008
Simon Buerger wrote:
> hi
> I would like to do some RTTI, but not with type-IDs, but in some more pretty way. I'll simply post some code to show you what I mean :) . My Question is now: Does anyone know, how to do sth alike with the current D implementation (maybe with templates, but I dont see a nice way) ? Or do you think it could be worth an extension for D 2.0 ?
> Krox
> 
> Code:
> 
> class Base {}
> class A : Base
> {
>     void function_A() { ... }
> }
> class B : Base {}
> {
>     void function_B() { ... }
> }
> 
> void main()
> {
>     Base x = ...
>         // checks if x is of type A, and if so, declares y as A alias of x with other type
>     if (x == A y)           y.function_A();
>     else if(x == B y)
>         y.function_B();
> }

this work?

if (auto y = cast(A)x)
	y.function_A();
else if(auto y = cast(B)x)
	y.function_B();

May 01, 2008
BCS wrote:
> this work?
> 
> if (auto y = cast(A)x)
>     y.function_A();
> else if(auto y = cast(B)x)
>     y.function_B();
> 

Well, honestly I'm really impressed. Thats perfectly what I wanted. Seems to be standard, but I didn't knew about it *lolz*. Okay, seems to be solved then. Thanks.
May 02, 2008
Simon Buerger Wrote:

> BCS wrote:
> > this work?
> > 
> > if (auto y = cast(A)x)
> >     y.function_A();
> > else if(auto y = cast(B)x)
> >     y.function_B();
> > 
> 
> Well, honestly I'm really impressed. Thats perfectly what I wanted. Seems to be standard, but I didn't knew about it *lolz*. Okay, seems to be solved then. Thanks.

OMG invalid cast doesn't throw exception????
May 02, 2008
terranium Wrote:

> Simon Buerger Wrote:
> 
> > BCS wrote:
> > > this work?
> > > 
> > > if (auto y = cast(A)x)
> > >     y.function_A();
> > > else if(auto y = cast(B)x)
> > >     y.function_B();
> > > 
> > 
> > Well, honestly I'm really impressed. Thats perfectly what I wanted. Seems to be standard, but I didn't knew about it *lolz*. Okay, seems to be solved then. Thanks.
> 
> OMG invalid cast doesn't throw exception????

Nope.  Invalid casts simply return null.  If you absolutely need an exception, then you can just wrap the cast in a templated function:

class DynamicCastException : Exception{
	public this(char[] reason){
		super(reason);
	}
}

T dyn_cast(T)(Object x){
    T result = cast(T)x;
    if(result is null) throw new DynamicCastException("Cannot cast to type " ~ T.stringof);
    return result;
}

class A{}

class B:A{}

class C{}

void main(){
	B x = new B();
	C y = dyn_cast!(C)(x);
}
May 02, 2008
Pragma Wrote:

> If you absolutely need an exception

And who don't? Yet another D misdesign to be worked around? And where will be more legacy design typos in the end? In C++ or in D?
May 02, 2008
terranium wrote:
> Pragma Wrote:
> 
> 
>>If you absolutely need an exception
> 
> 
> And who don't? Yet another D misdesign to be worked around? 
> And where will be more legacy design typos in the end? In
> C++ or in D?

In most cases forgetting to check the cast return will result in an seg-v from a dereferenced null because you almost always use it as the very next thing. Also it will never result in a miss use for the same reason, the pointer doesn't point to anything.

Having the "bad cast" -> null is very handy when you don't known if the cast will be good. It mean you can test it without invoking the exception system and all the overhead that entails.
May 02, 2008
"terranium" <spam@here.lot> wrote in message news:fvf93j$194u$1@digitalmars.com...
> Pragma Wrote:
>
>> If you absolutely need an exception
>
> And who don't?

I don't.

I perform downcasts extremely rarely.  When I do, it's usually in code like:

if(auto y = cast(Y)x)
    ...
else
    // not a Y, try something else

That is, the code is only executed if the cast succeeds.

Furthermore, it's a lot easier and more efficient to have the cast return null and throw an exception _only if needed_ than to throw an exception and then have to catch it:

try
{
    auto y = cast(Y)x;
    ...
}
catch(CastException e)
{
    // not a Y, try something else..
}

For that matter, some languages (like C#) have both kinds of casts - one that throws an exception and one that doesn't.  Either can really be implemented in the other, but the null-returning kind is more basic and efficient.


May 02, 2008
terranium wrote:
> Pragma Wrote:
> 
>> If you absolutely need an exception
> 
> And who don't? Yet another D misdesign to be worked around? And where will be more legacy design typos in the end? In C++ or in D?

In Java, I often find myself writing code like:

void process(Object o)
{
    if(o instanceof String)
    {
        String s = (String) o;
        // ...
    }
    else if(o instanceof List)
    {
        List<String> l = (List<String>) o;
        // ...
    }
}

It's much easier (and more efficient) to use the D way:

void process(Object o)
{
    if(auto s = cast(string) o)
    {
        //...
    }
    else if(auto l = cast(Seq!(string) o)
    {
        // ...
    }
}
May 04, 2008
terranium wrote:
> Pragma Wrote:
> 
>> If you absolutely need an exception
> 
> And who don't? Yet another D misdesign to be worked around? And where will be more legacy design typos in the end? In C++ or in D?

Actually, since you don't know if the cast is really valid, it failing is a regular outcome.

As such, an exception (which is reserved, appropriately, for *exceptional* events), is totally the wrong approach to use.

Note that with the current behavior, you can incur the runtime speed loss of throwing an exception if you _want_ to, by using the above templated wrapper, but if throwing an exception were the only possibility, you couldn't possibly get that speed back.

So it really is better this way. :)

 --downs
« First   ‹ Prev
1 2