class base {
int a;
protected:
template<class T>
class derived;
public:
base() {}
virtual ~base() {}
virtual void func() {}
static base* maker();
};
template <class T>
class base::derived
: public base
{
public:
derived() {}
virtual ~derived() {}
virtual void func() {
this->~derived(); //<--is this legal?
new (this) derived<int>(); //<--is this legal?
}
};
base* base::maker() {
return new derived<double>();
}
int main() {
base* p = base::maker(); //p is derivedA<double>
p->func(); //p is now derivedA<int>
delete p; //is the compiler allowed to call ~derived<double>()?
}
This is a Short, Self Contained, Correct (Compilable), Example of my code (which is basically reinventing any_iterator
for my own growth).
The question reduces down to: is it undefined behavior to destroy this
and reconstruct this
with a different type virtually derived from the same base, when neither has any additional members over the shared base? Specifically, are compilers allowed to call keep track of the static type, or is that technically nonconforming?
[EDIT] Several people pointed out that compilers may call the incorrect destructor if derivedA
is created on the stack. (1) I can't find anything in the standard that allows compilers to do so. (2) That was aside from what I intended by my question, so I have changed the code to show that derived
cannot be placed on the stack. base
can still be on the stack though.