Без typename SubType будет считаться статическим членом. Таким образом, это будет конкретная переменная или объект. В результате выражение T :: SubType * ptr будет умножением статического члена SubType класса T на ptr.
Это описание неверно применительно к приведенному вами примеру. В телах классов не может быть выражений, и никакие конструкции не анализируются как умножение. Однако в синтаксисе C ++ 03 есть конструкция, которая выглядит следующим образом
struct Base { int a; };
struct Derived : Base {
Base::a; // access-declaration
};
Эта конструкция устарела в C ++ 03, но все еще поддерживается и означает то же, что и следующая
struct Base { int a; };
struct Derived : Base {
using Base::a; // using-declaration
};
Поскольку вы не сказали компилятору, что T::SubType
является типом, и, следовательно, сказали компилятору, что он должен проанализировать его как тип объявления указателя, компилятор предположил, что T::SubType
- это имя в доступе. декларация. Следовательно, он ожидал точку с запятой сразу после него, и, следовательно, ожидал, что T
является базовым классом из MyClass<T>
(или что MyClass<T>
является производным классом из T
). Сообщение об ошибке фактически имеет его в обратном направлении:
if (! UNIQUELY_DERIVED_FROM_P (IDENTIFIER_TYPE_VALUE (cname),
ctype))
{
cp_error ("type `%T' is not derived from type `%T'",
IDENTIFIER_TYPE_VALUE (cname), ctype);
...
}
Пока макрос говорит
/* Nonzero iff TYPE is uniquely derived from PARENT. Under MI, PARENT can
be an ambiguous base class of TYPE, and this macro will be false. */
#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) ...