Очень часто встречающаяся проблема. Положите typename
:
template <class T>
class Test: public T
{
public:
void TestFunc()
{
typename T::SubClass bob;
}
};
T::SubClass
является зависимым именем . При разборе шаблона компилятор еще не знает, будет ли он типом. Поскольку он все еще может анализировать его (и собирать информацию, полученную таким образом), он предполагает, что это не тип. Но тогда строка должна быть выражением и пропустить оператор между двумя именами. typename
сообщит, что имя является типом, и строка станет объявлением.
Может быть неясно, почему это терпит неудачу выше, потому что вся строка не может быть выражением. Но есть и другая ситуация, когда невозможно принять решение о форме всего утверждения:
T::SubClass * bob;
Это умножение или объявление указателя? Компилятор предположит, что это умножение. Если позже при создании экземпляра шаблона выяснится, что T::SubClass
присваивает имя типу, появится сообщение об ошибке. typename
также скажет компилятору, чтобы он анализировал это как объявление, а не как выражение (принимая T::SubClass
в качестве типа).
Обратите внимание, что некоторые компиляторы могут по-прежнему работать без typename
(если я правильно помню, компилятор MSVC является одним из них). Я думаю, что это должно сопровождаться ограничением, что эти компиляторы не будут выполнять двухфазный поиск имен: они будут анализировать весь шаблон во время создания экземпляра, и все имена, даже те, которые не были видны в определении шаблона, будут найдено (в отличие от того, что сказано в Стандарте, который по-разному относится к поиску имени при определении / создании).
Для получения дополнительной помощи посетите FAQ по шаблону: FAQ по шаблонам C ++