В 5.2.7 - Dynamic cast [expr.dynamic.cast]
говорится, что для dynamic_cast<T>(v)
:
- Если
T
является типом указателя, v
должно быть r-значением указателя на полный тип класса - Если
T
является ссылочным типом, v
должен быть lvalue полного типа класса (спасибо usta за комментирование моего отсутствия this)
...
- В противном случае
v
должен быть указателем или значением l полиморфного типа
Таким образом, нет, значение (void*)
не допускается.
Давайте подумаем, что может означать ваш запрос: скажем, у вас есть указатель, который действительно соответствует Derived1*
, но код dynamic_cast
-ing знает только, что это void*
.Допустим, вы пытаетесь привести его к Derived2*
, где оба производных класса имеют общую базу.Внешне вы можете подумать, что все указатели будут указывать на один и тот же объект Base
, который будет содержать указатель на соответствующую таблицу виртуальной диспетчеризации и RTTI, поэтому все может висеть вместе.Но учтите, что у производных классов может быть несколько базовых классов, и поэтому необходимый подобъект класса Base
может не совпадать с тем, на который указывает Derived*
- доступный только как void*
.Это не сработает.Вывод: компилятор должен знать эти типы, чтобы он мог выполнить некоторую настройку указателей в зависимости от используемых типов.
Derived1* -----> [AnotherBase]
[[VDT]Base] <-- but, need a pointer to start of
[extra members] this sub-object for dynamic_cast
(в некоторых ответах говорится о том, что указатель, из которого вы производите преобразование, должен бытьполиморфного типа, с виртуальными функциями. Это все правильно, но немного вводит в заблуждение. Как вы можете видеть выше, даже если void*
относится к такому типу, он все равно не будет надежно работать без полной информации о типе, так какреальная проблема заключается в том, что void*
предположительно указывает на начало производного объекта, тогда как вам нужен указатель на подобъект базового класса, из которого происходит тип приведения.)