"really" dynamic cast

J

Jordi Vilar

Hi All,

Is there a way to dynamic_cast a pointer to a type defined by a
type_info*?

something like:
type_info *info_of_type_to_cast = typeid(type_to_cast);
type_to_cast *casted =
really_dynamic_cast<info_of_type_to_cast>(my_data_ptr);

I expect to work as:
type_to_cast *casted = dynamic_cast<type_to_cast>(my_data_ptr);

Of course it should raise a bad_cast exception if types are
unrelated, and all other standard behavior of dynamic_cast...

thanks,

Jordi Vilar
 
R

Rolf Magnus

Jordi said:
Hi All,

Is there a way to dynamic_cast a pointer to a type defined by a
type_info*?

something like:
type_info *info_of_type_to_cast = typeid(type_to_cast);
type_to_cast *casted =
really_dynamic_cast<info_of_type_to_cast>(my_data_ptr);

What would that be good for? You already know the target type at compile
time, since you created the 'casted' pointer with it.
I expect to work as:
type_to_cast *casted = dynamic_cast<type_to_cast>(my_data_ptr);

Of course it should raise a bad_cast exception if types are
unrelated, and all other standard behavior of dynamic_cast...

dynamic_cast doesn't throw at all when used with pointers.
 
D

Donovan Rebbechi

Hi All,

Is there a way to dynamic_cast a pointer to a type defined by a
type_info*?

something like:
type_info *info_of_type_to_cast = typeid(type_to_cast);
type_to_cast *casted =
really_dynamic_cast<info_of_type_to_cast>(my_data_ptr);

I expect to work as:
type_to_cast *casted = dynamic_cast<type_to_cast>(my_data_ptr);

Of course it should raise a bad_cast exception if types are
unrelated, and all other standard behavior of dynamic_cast...

I agree with Rolf's response -- what's the motivation for this ?

The question as presented doesn't make sense -- the point of dynamic_cast
is to attempt convert a type not known at compile to type known at compile.

Or to put it another way, how does a derived class pointer where you don't
know the type of pointer at compile time better than a base class pointer ? To
me, it appears that the latter is C++'s way of modelling the former.

Cheers,
 
J

Jordi Vilar

Hi All again,
I agree with Rolf's response -- what's the motivation for this ?

I'm currently developing an implementation of an interface containing
a method:

virtual void* cast_to(const type_info &ti) throw(nointerface,
bad_typeid) = 0;

a trivial implementation is:

void* CMyImpl::cast_to(const type_info &ti)
{
if(ti == typeid(IInteface1*))
return static_cast<IInterface1*>(this);
if(ti == typeid(IInteface2*))
return static_cast<IInterface2*>(this);
...
throw nointerface();
}

but I'm looking for a simpler and less error prone implementation. I
found __RTDynamicCast in MS VC++ that just does it (VC++ implements
dynamic_cast using this undocumented helper function)

void* CMyImpl::cast_to(const type_info &ti)
{
void *coerced = __RTDynamicCast(this, 0, typeid(CMyImpl*), ti, 0);
if(coerced == NULL)
throw nointerface();
return coerced;
}

This resolves all casts as dynamic_cast does, but this is not
standard, so I don't want it (I need a portable code)
The question as presented doesn't make sense -- the point of dynamic_cast
is to attempt convert a type not known at compile to type known at compile.

Or to put it another way, how does a derived class pointer where you don't
know the type of pointer at compile time better than a base class pointer ? To
me, it appears that the latter is C++'s way of modelling the former.

I agree with you, you cannot use data of an unknown type! so this is
not very useful and you can obtain the same functionality with
dynamic_cast (if you know the type to cast to in compile-time). But
the interface I NEED to implement requires such semantics to be
supported.

It also enables to query for a type known in another layer. The bad
thing is the void*, but it also happens with dynamic_cast<void*>() !!

The only interesting benefit of this scheme is the control of the cast
process, so you can control the interfaces you want to expose or hide,
beyond the public/protected/private scheme. Also you can resolve
ambiguities (what dynamic_cast doest when requesting a cast to a base
interface of a two implemented interfaces (multiple inheritance of
interfaces deriving from a common base interface)?) And achieving this
hiding at all the implementation class and using pure virtual
interfaces.

This is a C++ replacement of the discovering services in other systems
(reflection in Java/.NET, or IUnknown::QueryInterface() in COM, or the
equivalent in CORBA, etc.)

Maybe this is not possible with the current standard, so bad luck...
:(

Thanks for your comments.

Regards,

Jordi Vilar
 
D

Donovan Rebbechi

[snip]

OK reading the text at the bottom, I have some idea what you're trying to
do.
void* CMyImpl::cast_to(const type_info &ti)
{
void *coerced = __RTDynamicCast(this, 0, typeid(CMyImpl*), ti, 0);
if(coerced == NULL)
throw nointerface();
return coerced;
}

This resolves all casts as dynamic_cast does, but this is not
standard, so I don't want it (I need a portable code)

OK. I see what it's doing. It attempts to safely cast the current object to
one of type ti and returns the appropriate pointer if the cast worked.

One thing worth thinking about is making your own more powerful objects for
representing types, and in particular, make the type object responsible for
handling the conversions.

e.g. here's a really simple example:

struct type
{
public:
virtual void* convert (const type& x) = 0;
};

template <typename T>
struct type_impl : type
{
public:
virtual void* convert (const type & x)
{
return dynamic_cast<T*>(&x);
}
};

void* CMyImpl::cast_to(const type &ti)
{
return ti.convert(this);
}

Though this looks static (because you have templates), you could actually compile your
templated objects into instantion modules, and load them dynamically (IOW add types to
a running system).

Cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top