Sorry, i better test my code before saying things.
In fact you can use static cast like this and than avoid overhead: static_cast<Super2*>(static_cast<Sub*>(ptr))
To do so you have to implement m after the declarations of Super2 and Sub.
But by using static cast, the cast is not checked at run-time so static_cast<Super2*>(static_cast<Sub*>(ptr)) could return an invalid pointer. But I guess it's not a problem if it's just for comparing pointers. Any objections?