reinterpret_cast<Base**>(ppDerived)
четко определено.Разыменование результата, если он указывает на указатель на производное, является неопределенным поведением, а не тем, что вам разрешено делать.«Кажется, что он работает нормально» - это один из возможных симптомов UB.
Что вам, вероятно, нужно:
Base* foo() {
return new Derived(5, 7);
}
Derived* bar() {
return static_cast<Derived*>(foo());
}
Это не содержит UB и логически эквивалентно.
Или вы можете сделать:
template<class...Ts>
using sink=std::function<void(Ts...)>;
void foo(sink<Base*> ppb) {
ppb(new Derived(5, 7));
}
void bar(sink<Derived*> ppd) {
foo([&](Base*b){ ppd(static_cast<Derived*>(b)); });
}
или даже
void foo(Base** ppb) {
*ppb = new Derived(5, 7);
}
void bar(Derived** ppd) {
Base*p=0;
foo(&p);
*ppd=static_cast<Derived*>(p);
}