Во-первых, ваш код использует размер указателя вместо разыменованного указателя, поэтому он не будет работать, даже если gcc не будет жаловаться.
Во-вторых, трюк sizeof должен работать с приведениями 0, а не с фактическими указателями или объектами - это гарантирует нулевые накладные расходы, а также то, что он не будет выполняться, пока вы не сделаете это правильно.
В-третьих, вам нужно объявить 2 шаблонных класса или структуры, один из которых является производным только от D, а другой - от D и виртуального B, а затем привести 0 к их указателям, разыменовать их и затем sizeof.
4-й - Есть ли у вас какая-либо серьезная причина для того, чтобы пытаться быть политически корректным с использованием static_cast вместо прямой трансляции здесь? Компилятор всегда будет выводить из того, что вы ищете больше нытья, и в этом случае вы определенно нет.
Кстати, вам не нужно захватывать полный код у Александреску - просто захватите основную технику, которая в основном просто:
sizeof(*((T*)0))
Александреску действительно хорош в уборке после уловки.
Да, и помните, что компилятор не должен оценивать размер аргументов или создавать неиспользуемые шаблонные классы и структуры - поэтому, если это так, то это ошибка компилятора, и если вы заставляете его это делать, то это ваша ошибка: -)
Как только вы это получите, вам нужно точно и в положительных терминах определить, что ваше утверждение «если указатель на Derived может быть приведен из указателя на Base без dynamic_cast <>», фактически означает в терминах отношений класса - просто сказать « без оператора / функции Q "не делает проблему хорошо определенной, и вы не можете решить то, что не можете определить - честно: -)
Так что просто сделайте первый чистый шаг, который компилируется, а затем попытайтесь определить, каким образом два случая, о которых вы упомянули, будут на самом деле разными - что будет иметь или сделает один, а другой - нет.