Причина в том, что при создании экземпляра шаблона класса создаются все его объявления (не определения) его функций-членов. Шаблон класса создается именно тогда, когда требуется полное определение специализации. Это тот случай, когда он используется в качестве базового класса, например, как в вашем случае.
Так что получается, что A<B>
создается в
class B : public A<B>
, в этот момент B
еще не является полным типом (это после закрывающей скобки определения класса). Однако для объявления A<B>::action
требуется, чтобы B
было завершено, потому что оно сканирует его в объеме:
Subclass::mytype
Что вам нужно сделать, это отложить создание экземпляра до некоторой точки, в которой B
завершена. Один из способов сделать это - изменить объявление action
, сделав его элементом шаблона.
template<typename T>
void action(T var) {
(static_cast<Subclass*>(this))->do_action(var);
}
Это все еще безопасно для типов, потому что, если var
не того типа, передача var
в do_action
завершится неудачей.