You are performing a cross-cast; IBase
and IDerived
are unrelated. You need to cast to Derived
first and then to IDerived
. If you used a static_cast
rather than a C cast the compiler would have caught this for you at compile-time.
I assume you know that the IBase
is really a Derived
because you used a C cast, but if you don't then you can also use dynamic_cast
to perform cross-casts safely.
EDIT: If you can't use RTTI and you don't know the dynamic type of the object then virtual inheritance and dynamic_cast
go out of the window. When you call CreateDerived
it looks like you do know the dynamic type of the object (because of its template arguments) so you could have a std::map<IBase*, IDerived*>
and then after the CreateDerived<TT, TB, TI...>()
call you can static_cast
the IBase*
to Derived<TT, TB, TI...>*
and then insert the pointer as both the key and value into the map.
Just enable RTTI; this is getting complicated. >.<
EDIT 2: Alternatively, you seem to know that the object pointed at by the IBase*
does also derive from IDerived*
. If you can modify the class hierarchy you can have an abstract base class that derives from both IBase
and IDerived
and then have Derived
derive from this new base class. Then you can static_cast
from an IBase*
to the new class in the hierarchy and then to IDerived*
.
It would look something like this:
class IBase { virtual void Foo() = 0; };
class Base : public IBase { virtual void Foo() { } };
class IDerived { virtual void Bar() = 0; };
class BaseAndDerived : public Base, public IDerived { };
template<typename TT, typename TB, typename... TI>
class Derived : public BaseAndDerived { virtual void Bar() {}};