Вам нужно ключевое слово template
template<class TA>
template<class TBA>
struct A<TA>::B : C<typename D<TA>::template T<TBA> >
{
int foo;
};
GCC правильно поставить здесь диагностику. Это потому, что T
нельзя найти в зависимой области действия D<TA>
. Значение <
после него зависит от того, является ли T
шаблоном или нет. Стандарт гласит, что T
следует считать не шаблоном, и поэтому T
не может сопровождаться списком аргументов шаблона.
template
похож на typename
в том смысле, что он указывает компилятору обрабатывать T
как шаблон, а <
является началом списка аргументов в любом случае. Стандарт гласит в пунктах 14.2/2
и 14.2/4
Чтобы имя шаблона было явно определено аргументами шаблона, должно быть известно, что имя относится к
в шаблон.
Когда имя специалиста шаблона участника появляется после. или -> в выражении postfix или после спецификатора nested-name в квалифицированном идентификаторе, а выражение postfix или квалифицированный идентификатор явно зависит от параметра-шаблона (14.6.2), имя шаблона элемента должно быть с префиксом шаблона ключевого слова. В противном случае предполагается, что имя не является шаблоном.
В вашем случае T
появляется после спецификатора вложенного имени D<TA>
, который зависит от параметра-шаблона TA
. Для правильного разбора спецификатора typen конструкция D<TA>::T<TBA>
должна интерпретировать T
как имя шаблона класса, которое 14.2
запрещает.
На эту тему всегда полезно попробовать и скомпилировать с Clang
main1.cpp:21:37: error: use 'template' keyword to treat 'T' as a dependent template name
struct A<TA>::B : C<typename D<TA>::T<TBA> >
^
template
1 error generated.