Последнее приведение в main () неверно синтаксически и не эквивалентно коду в шаблоне, вы не можете вывести объект из объекта (вы можете выполнить переход вниз, вызывая сокращение типа). В приведенных выше шаблонах вы разыгрываете ссылки.
Derived&
может быть привязано к Base&
, static_cast
не имеет возможности проверить это. CRTP обеспечивает это, поскольку this
указывает на хранилище производного типа, *this
дает ссылку, которую можно безопасно преобразовать в Derived&
эталонный объект.
Ссылка на Another
не может быть привязана к ссылка на Base
, когда Base
не является базовым классом Another
. В этом случае приведение указателей или ссылок с использованием static_cast
недопустимо.
Код шаблона допустим, в случае работы CRTP, потому что код шаблона устанавливается там, где Derived имеет достаточно полный тип, т. Е. Где использовался шаблон. Сам шаблон ничего не генерирует и не компилируется, проверяется только на корректность.
Тем не менее, в CRTP некоторые вещи не возможны, например, использовать внутри декларации вложенного типа базового класса из класса Derived как полные типы по простой причине: они не являются полными и не подлежат прямому поиску, в отличие от переменных-членов и функций. Если такое использование требуется, то третий должен быть определен перед Base, ограничивая требуемые объявления.