Вот пример кода шаблона на основе CRTP , который я использовал, чтобы попытаться решить этот вопрос: Требование переопределенных виртуальных функций для вызова базовых реализаций . Я бы разместил здесь код, но строки длинные и их легче читать на codepad.org (при необходимости я опубликую здесь). Конечно, это некрасиво и несколько искусственно, хотя и работает. Но то, что я сначала не осознавал, это то, что, хотя он компилируется как в MSVC ++, так и в GCC, некоторые типы шаблонов на самом деле не определены. Часть, о которой я спрашиваю, - это несколько длинных внутренних if( typeid( Derived(N) ) != typeid( Derived(N-1))
(символьных обозначений) в функции TBase::OnEvent
сверху.
Вы не можете typdef
этих типов, это будет ошибка компиляции - просто недостаточно производных классов для определения типа с такой длинной цепочкой ...::TDerived::...
, поэтому вы получите, правильно, ошибку компиляции TDerived is not defined in TBase
. И все же компилятор ест их через typeid
. Когда я проверял выходные данные компилятора отладчика MSVC ++ (с полной символической информацией), кажется, что все эти длинные ...::TDerived::...
, которые не должны действительно приводить ни к какому классу, в typeid
разрешаются компилятором просто в последний TDerived04
в цепочке классов , И RTTI тянется для этого последнего класса в цепочке классов, независимо от того, сколько ...::TDerived::...
у меня есть.
Учитывая, что MSVC ++ и GCC делают это (хотя у меня есть доступ к GCC только через codepad.org), мой вопрос следующий: это как-то определяет поведение typeid
? Почему тогда typedef
любого из этих длинных ...::TDerived::...
не разрешается до TDerived04
?
РЕДАКТИРОВАТЬ: я имею в виду, я счастлив typedef
не разрешается до TDerived04
, это будет катастрофой для всех, кто использует typedef
, но почему такая несоответствие между typeid
и typedef
?
РЕДАКТИРОВАТЬ: GCC принимает объявление переменной TDerived04::TDerived04::TDerived04::TDerived04 lD4;
. И тип просто TDerived04
в конце. Есть ли правило для свертывания разрешения области? Очевидно, что и MSVC ++, и GCC, похоже, делают то же самое в typeid
, но MSVC ++, в отличие от GCC, не может обрабатывать другие сценарии - он выдает ошибку компиляции, требуя аргументов для конструктора (ов).