После попытки отладить неудачное динамическое преобразование вниз, я в конце концов обнаружил, что причина, вероятно, заключается в следующем: type_info::hash_code для типа, к которому он приводится, отличается в зависимости от того, где в коде он вызывается. Однако type_info::name остается точно таким же. К сожалению, я не могу воспроизвести поведение в минимальном примере, поскольку оно появляется в довольно запутанном контексте. Поэтому я, по сути, ищу ключи к разгадке того, что может быть причиной такого поведения, и, следовательно, в каком направлении я могу решить эту проблему.
Короче говоря, если это связано, тип выглядит так (ОТРЕДАКТИРОВАНО):
class A {...}
template < template <class> class>
class B : virtual public A {...}
template < template <class> class>
class C : virtual public A {...}
template < template <class> class>
class D : public B, public C {...}
template <class>
class E {...}
Проблема выглядит так:
D<E>* d = build_d();
B<E>* b = d;
A* a = d;
dynamic_cast<D<E>*>(b);//returns correct pointer
dynamic_cast<D<E>*>(a);//returns 0, and really shouldn't !!
typeid(B<E>).hash_code();//differing depending where in the code this is called
Вызовы type_info::hash_code выполняются внутри разных библиотек (моих собственных). Покопавшись, я нашел опцию компилятора -rdynamic с GCC (даже если я использую Clang). Я не уверен, что это может быть как-то связано с моей проблемой.
РЕДАКТИРОВАТЬ: В конце концов я нашел хорошую подсказку. К сожалению, пока нет решения. Похоже, проблема может быть связана с Qt в конце.
Проблема возникает в функции слота. Когда слот вызывается сигналом, нисходящее приведение dynamic_cast не выполняется. Но если вместо этого я вручную вызову слот (например, в main), он преуспеет. И если вручную вызывать слот, то запускать его по сигналу, тоже получается. Аргумента для сигнала нет, а содержимое слота "нейтрализовано" и не зависит ни от каких параметров. На 99,99% уверен, что проблема не в ошибке алгоритма распределения.
Похоже qt_static_metacall при вызове слота как-то теряет след свойств приведения. Может ли иметь к этому какое-то отношение тот факт, что предварительно скомпилированный связанный moc?